0

I'm trying out triple pointers for the first time. This question is where I got the info on how to allocate a triple pointer and this is how the triple pointer has been allocated:

//In this case size will always be 4
int size = countLines(file);
printf("size: %d\n", size);
char*** tripleptr = malloc(sizeof(*tripleptr)*size);
int i = 0, k = 0, j = 0;
for(; i < size; i++){
    tripleptr[i] = malloc(sizeof(*(tripleptr[i]))*size);
    for(; k< size; k++){
        tripleptr[i][k] = malloc(sizeof(*(tripleptr[i][k]))*512);
    }
}

If I try to copy a string literal into position [0][0] like this

strcpy(tripleptr[0][0], "something");

it works perfectly (same thing for [0][1] to [0][3]), but

strcpy(tripleptr[1][0], "something");

doesn't (it makes the program go into Segmentation Fault). What is it that could be causing such a weird behavior? I can't find any indexing mistake in the memory allocation part

dbush
  • 205,898
  • 23
  • 218
  • 273

2 Answers2

2

The problem is in your loops:

int i = 0, k = 0, j = 0;
for(; i < size; i++){
    tripleptr[i] = malloc(sizeof(*(tripleptr[i]))*size);
    for(; k< size; k++){
        tripleptr[i][k] = malloc(sizeof(*(tripleptr[i][k]))*512);
    }
}

You initialized i and k before entering the nested loop, but you don't reset k when the inner loop restarts on the next iteration. This means that you only allocated memory for the first row of strings. So tripleptr[1][0] is uninitialized, and dereferencing that pointer gives you undefined behavior.

Explicitly initialize youf loop control variables each time:

int i, k;
for(i=0; i < size; i++){
    tripleptr[i] = malloc(sizeof(*(tripleptr[i]))*size);
    for(k=0; k< size; k++){
        tripleptr[i][k] = malloc(sizeof(*(tripleptr[i][k]))*512);
    }
}
dbush
  • 205,898
  • 23
  • 218
  • 273
0

the following proposed code:

  1. illustrates how the block of code should be done
  2. indicates how much memory is actually being allocated
  3. reminds you that the code needs to check for errors
  4. indicates how to handle the error, if one occurs

and now, the proposed code:

//In this case size will always be 4
int size = countLines(file);
printf("size: %d\n", size);

char*** tripleptr = malloc(sizeof(*tripleptr)*size);

for(int i = 0; i < size; i++)
{
    tripleptr[i] = malloc(sizeof(*(tripleptr[i]))*size); // is 16 bytes each iteration, assuming a pointer is 4 bytes

    for(int k = 0; k< size; k++)
    {
        tripleptr[i][k] = malloc(sizeof(*(tripleptr[i][k]))*512); // is 4k bytes each iteration
    }
}

Note: for robustness:

when calling any of the heap allocation functions: malloc(), realloc(), calloc() : always check (!=NULL) the returned value to assure the operation was successful.

If not successful, call perror( "my error message" ); as that will output to stderr, both your error message and the text reason the system thinks the error occurred. And remember to pass each successfully allocated heap memory pointer to free() before exiting

user3629249
  • 16,402
  • 1
  • 16
  • 17