1

I am trying to write data into a variable length two dimensional array and my program keeps seg-faulting when I call myfunc but it works fine when I try to perform the same manipulation outside of a function. I can tell that the issues is that the address pointed to at array[0] doesn't equal the address pointed to at data[0]. Can someone advise me as to the root cause of this issue and proper way to rewrite myfun.

void myfun(unsigned char **array){
    printf("array = %p, array[0] = %p\n", array, array[0]);
    //This line below causes a segfault
    strcpy(array[0], "Position0");
}

int main(void) {
    int row = rand() % 5 + 1;   // random number between 1-5
    int col = rand() % 10 + 20;   // random number between 20-29
    unsigned char data[row][col];

    printf("data = %p, data[0] = %p\n", data, data[0]);

    //This function call causes a segfault
    myfun(data);
    printf("%s\n", data[0]);

    //This works
    strcpy(data[1], "Position1");
    printf("%s\n", data[1]);

    return 0;
}
4
  • In your text you say you get a segfault when you perform the operation inside myfun, but not when you perform it outside the function; the comment in your code says the opposite. Commented Feb 9, 2016 at 4:38
  • I just updated the comments in the code to be more clear. The line that causes the segfault is "strcpy(array[0], "Position0");" Commented Feb 9, 2016 at 4:43
  • 1
    Your compiler should have warned you that char[x][y] is incompatible withchar**, and you should have listened to that warning, because it's true. If it didn't warn you, learn how to enable warnings. Commented Feb 9, 2016 at 5:06
  • Possible duplicate of Is 2d array a double pointer? Commented Feb 9, 2016 at 5:07

2 Answers 2

3

Since you are clearly using C99 or later and a compiler with VLA (variable length array) support, you can write the function correctly quite easily:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void myfun(int rows, int cols, char array[rows][cols])
{
    printf("array = %p, array[0] = %p\n", array, array[0]);
    strcpy(array[0], "Position0");
    printf("a[0] = [%s]\n", array[0]);
}

int main(void)
{
    int row = rand() % 5 + 1;   // random number between 1-5
    int col = rand() % 10 + 20;   // random number between 20-29
    unsigned char data[row][col];

    printf("data = %p, data[0] = %p\n", data, data[0]);

    myfun(row, col, data);
    printf("%s\n", data[0]);

    strcpy(data[1], "Position1");
    printf("%s\n", data[1]);

    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

1

The problem is the function definition. If you want to pass a matrix the way you did, you have to allocate it dynamically, but that's another story. I'll explain the error.

The C language actually implement the static matrices as a single array of size row*col. That is for efficiency.

When you pass the static matrix to that function, you got a problem: it expects a double pointer, but what you pass is actually a single pointer requiring the number of columns. You have to write like this:

void myfun(unsigned char array[][col]){ ...

That's how you should define it, where col is the number of columns.

The problem's that you don't know the number of columns, it's variable, so I suggest you use malloc or calloc to alocate a dynamic matrix.

Editing: look at this link posted as comment by n.m. for details on the static matrix that C implements: Is 2d array a double pointer?

3 Comments

With C99 or C11 and VLA (variable-length array) support, you can handle it cleanly without needing dynamic memory allocation.
I like the malloc method: I got it working with the following code: data2 = (unsigned char**)malloc(row * col); myfun_malloc(data2); 'void myfun_malloc(char** array) { printf("In myfun_malloc: array = %p, array[2] = %p\n", array, (array + (2 * sizeof(char*))) ); strcpy(array + (2 * sizeof(char*)), "Position2"); printf("a[2] = [%s]\n", (array + (2 * sizeof(char*))) ); }
I also would rather using the dynamic rather than semi-dynamic solution, in this specific case. Nevertheless, I appreciate the feedback on the VLA. It's important to know the difference in efficiency of using semi-dynamic allocated arrays.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.