-3

I have the following code:

int width = 10;
int height = 9;

float** matrix = (float**) malloc(height*sizeof(float));

for (unsigned int i = 0; i < height; i++)
    matrix[i] = (float*) malloc(width*sizeof(float));

//This works
matrix[6][0] = 3.0f;

for (unsigned int j = 0; j < width; j++) {
    for (unsigned int i = 0; i < height; i++) {
        //This fails on [6][0]
        matrix[i][j] = 3.0f;
    }
}

I am attempting to create a 2D array and initialise it however a segmentation fault is received when setting the value of matrix[6][0] within the loop. What I'm finding very strange is that no error is thrown when I set matrix[6][0] outside of the loop. It's my understanding that a segmentation fault occurs when illegal memory is accessed but I cannot find any reason why different memory is being accessed within the loop. I have even examined the assembly code to find out what's happening but I cannot find the problem.

Update: The code was part of a CUDA program (C++) but my brain was half thinking about C and half about C++, hence why it became a mess.

John Wheal
  • 9,908
  • 6
  • 29
  • 39
  • Note that it is [redundant and potentially dangerous to cast the result of malloc and friends in C](http://stackoverflow.com/q/605845/253056). (Doubly so in the above code!) – Paul R Mar 30 '16 at 16:52
  • There is no 2D array and nothing which can be used as one in your code. A pointer is not an array! And your wildly casting for the first `malloc` is a clear signal you lack some fundamental basics about pointers, too - no offence (honestly!), just a fact. – too honest for this site Mar 30 '16 at 16:54
  • Also C and C++ are different languages. Don't use both tags if the question is about one of them only. If in doubt, always tag for the compiler you use. – too honest for this site Mar 30 '16 at 16:58
  • Thanks @Olaf - the code was part of a CUDA program (C++) but my brain was half thinking about C and half about C++, hence why it became a mess. – John Wheal Mar 30 '16 at 17:17

2 Answers2

2
float** matrix = (float**)(float*) malloc(height*sizeof(float));

Instead of sizeof(float) use sizeof(float *) . You need to allocate memory for height number of float pointers .

So your code goes like this -

float** matrix = malloc(height*sizeof(float *));

Your code produces seg fault while using loop as you don't correct amount of memory for float pointers and you end up accessing invalid memory , thus getting undefined behaviour.

Note- Don't use cast for malloc . And check retrun of malloc.

ameyCU
  • 16,489
  • 2
  • 26
  • 41
2

Here is the refined code:

int width = 10;
int height = 9;

float **matrix = malloc(height * sizeof (float *));

for (size_t i = 0; i < height; i++)
    matrix[i] = malloc(width * sizeof(float));

matrix is "a pointer to pointers to floats", while matrix[i] are "pointers to floats".

nalzok
  • 14,965
  • 21
  • 72
  • 139
  • That won't compile it says "error: a value of type "void *" cannot be used to initialize an entity of type "float **" – John Wheal Mar 30 '16 at 16:58
  • @JohnWheal That must be because you maybe compiling it with C++ compiler . For C these cast are not needed . – ameyCU Mar 30 '16 at 17:02
  • @ameyCU This is actually part of a CUDA program and so it is being compiled with a C++ compiler. Does this change things? – John Wheal Mar 30 '16 at 17:05
  • @JohnWheal Then maybe you need to apply cast . Or use `new` and `delete` . – ameyCU Mar 30 '16 at 17:08