5

gcc 4.4.3 c89

I have the following source code. And getting a stack dump on the printf.

char **devices;
devices = malloc(10 * sizeof(char*));

strcpy(devices[0], "smxxxx1");

printf("[ %s ]\n", devices[0]); /* Stack dump trying to print */

I am thinking that this should create an char array like this.

devices[0]
devices[1]
devices[2]
devices[4]
etc

And each element I can store my strings.

Many thanks for any suggestions,

== Added correction ===

for(i = 0; i < 10; i++)
{
    devices[i] = malloc(strlen("smxxxx1")+1);
}
sepehr
  • 17,110
  • 7
  • 81
  • 119
ant2009
  • 27,094
  • 154
  • 411
  • 609

6 Answers6

5

You have allocated memory for an array of pointers. You need to allocate the memory for each element to store the string

e.g.

#define NUM_ELEMENTS 10
char **devices;
devices = malloc(NUM_ELEMENTS  * sizeof(char*));

for ( int i = 0; i < NUM_ELEMENTS; i++)
{
    devices[i] = malloc( length_of string + 1 );
}
mmmmmm
  • 32,227
  • 27
  • 88
  • 117
4

devices[0] is a char *, but you haven't allocated any storage for it. Do this instead:

char **devices;
devices = malloc(10 * sizeof(char*));

devices[0] = strdup("smxxxx1");

printf("[ %s ]\n", devices[0]);

Eventually, you'll have to free the memory allocated by strdup():

free(devices[0]);
Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
3

You have allocated memory for storing 10 char pointers. To store a string at these memory location you have to allocate memory for each of them. Basically you need something like device[0] = malloc(stringLen + 1); for each pointer.

Naveen
  • 74,600
  • 47
  • 176
  • 233
2

You only have allocated an array of pointers to character-arrays. You will have to allocate memory for each string you plan to store:

char **devices;
devices = malloc(10 * sizeof(char*));

//Added this line:

devices[0] = (char*)malloc(strlen("smxxxx1")+1);
strcpy(devices[0], "smxxxx1\0");

printf("[ %s ]\n", devices[0]); /* Stack dump trying to print */
sum1stolemyname
  • 4,506
  • 3
  • 26
  • 44
  • 2
    Your strings really don't need to include `\0` explicitly, they already are null terminated – Hasturkun May 12 '10 at 09:02
  • Just wondering as an extra precaution. Should the actual char array be NULL terminated. I have 10 elements. However, the 10th should be NULL. This is in case you are looping through displaying and you want to stop at the NULL? Just an idea Thanks. – ant2009 May 12 '10 at 09:10
  • 1
    @robUK: Using NULL as a sentinel value at the end of an array is sometimes common practice (e.g. `argv`). It depends on the situation; sometimes there might not be an appropriate value that can be used as a sentinel (what if NULL were a legitimate element in your array? what if you aren't dealing with an array of pointers?). – jamesdlin May 12 '10 at 09:55
1

you have allocated space for pointers (devices) but have not allocated space for strings you are going to store.

0

devices is an array of pointers. You are copying the string "smxxxx1" over the array, when it looks like you want to set element 0 to point to the string.

Instead of the strcpy() try:

devices[0] = "smxxxx1"

or

devices[0] = strdup("smxxxx1")

Edit:

On a 32 bit system, devices[0] is composed of four bytes. These four bytes are being overwritten with the byte values of the first four characters of the string "smxxxx1". In ascii these are 0x73, 0x6D, 0x78, 0x78. Assuming little-endian addressing, you end-up with devices[0] containing a pointer to the address 0x78786D73. This address will almost certainly not be valid within the process. When the call to printf() tries to dereference this invalid pointer the OS triggers a segmentation fault and dumps core.

The problem was that the OP was incorrectly treating the devices variable as a string (array of char) when initialising it. Its actually an array of pointers to char, and printf() is interpreting it as such.

Andy Johnson
  • 7,938
  • 4
  • 33
  • 50