0
double **matrix = NULL;
matrix = (double **)malloc(sizeof(double *) * N);   // N is the size of the square matrix

for(int i=0; i<N; i++)
{
   matrix[i] = (double *)malloc(sizeof(double)*N);
}

// Works good up to the next part
for(int i=0; i<N; i++)
{
   for(int j=0; j<N; j++)
   {
      printf("Value: %f", matrix[i][j]);
   }
}

I'm trying to create a two dimensional array of doubles by using the method above (create an array of pointers, and then each pointer gets an array of doubles). However, as soon as I try to print the first element matrix[0][0], I get a seg fault. I've seen some other posts that do almost the same thing, except I can't get mine to work.

stealthysnacks
  • 1,091
  • 1
  • 12
  • 16
  • 2
    Is this meant to be C or C++ ? – Paul R May 07 '13 at 05:49
  • Supposed to all be C. I can convert from C++ to C if needed though. – stealthysnacks May 07 '13 at 05:51
  • Can't see any problems in your code. Maybe you tried to access `matrix[0][0]` after you freed it ? (hmmm... is it a right form of past for `free` - `freed` ??? ) – borisbn May 07 '13 at 05:53
  • looks good to me, too. Toss that sucker in a debugger and tell us where it crashes and the values of matrix and matrix[i] are – xaxxon May 07 '13 at 05:54
  • 1
    Your code is fine. We are going to need to see an SSCCE (http://sscce.org/) that actually demonstrates the problem. – NPE May 07 '13 at 05:55
  • also, you shouldn't really call this a two dimensional array. It doesn't really have those properties. It only seems the same because you can use similar syntax to get to your elements. – xaxxon May 07 '13 at 05:56
  • 1
    (1) Do not cast the result of `malloc`. This may suppress important compiler messages. (2) Build an [sscce](http://sscce.org) – n. m. could be an AI May 07 '13 at 05:59
  • @n.m. you can't avoid cast **from** `void*`. you can (and maybe should) avoid it when casting **to** `void*` – borisbn May 07 '13 at 06:01
  • 1
    @borisbn: wrong.Have you tried? Note this is C, not C++. – n. m. could be an AI May 07 '13 at 06:03
  • @borisbn void* will be cast to other pointer types implicitly and its the natural way but the other way round needs the explicit cast(other* to void* i.e). – Koushik Shetty May 07 '13 at 06:04
  • @n.m. Sorry. My fault. I tried it in ideone, had an error, but forgot to change language to C. Sorry once more )) – borisbn May 07 '13 at 06:06
  • This is not a 2D-array, it's a heap fragmentation fiasco. [How to correctly set up, access, and free a multidimensional array](http://stackoverflow.com/questions/12462615/how-do-i-correctly-set-up-access-and-free-a-multidimensional-array-in-c). – Lundin May 07 '13 at 06:10
  • (gdb) 0x00000000004009e7 in print_matrix (matrix=0x0, size=10) at matrix.c:142 print_matrix is the function I'm calling it from and this is where it seg faults – stealthysnacks May 07 '13 at 06:21
  • 1
    You have not posted the actual program that fails. No one therefore can tell why it fails. Please remember, SSCCE is not just a good idea, it's the law. – n. m. could be an AI May 07 '13 at 06:26
  • @n.m. Except nobody knows what that acronym means. All you need to ask a proper question on SO is common sense. – Lundin May 07 '13 at 06:31
  • So my matrix is apparently null. Is it because I'm passing it into a function to allocate memory? It's probably a pass-by-value issue or something I'm guessing.. – stealthysnacks May 07 '13 at 06:37
  • 1
    @Lundin: SSCCE was linked to in the comments to this question at least twice. [This](http://sscce.org) is yet another link, just in case. You can't have too many. SSCCE *is* this site's common sense, which is alas not that common. – n. m. could be an AI May 07 '13 at 06:42

2 Answers2

3

Syntax-wise, there is nothing wrong with your code. Either you aren't showing the whole code, or (less likely) the program ran out of memory and you didn't check the result of malloc to find out about that.

Program design-wise, you shouldn't use the fragmented pointer to pointer syntax; it creates N arrays all over the heap, instead of one single true 2D array allocated in adjacent memory cells. Heap fragmentation is bad for program performance and may cause various other problems (depending on system).

Casting the result of malloc is pointless in C. On old C compilers, it is even harmful.

You don't give the items of the array any values before printing them. To set them all to zero, either use memset or replace malloc with calloc.

You should fix the above mentioned issues and rewrite your code to this:

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

double (*matrix)[N];  // an array pointer
matrix = calloc(1, sizeof(double[N][N])); // pointing at one true 2D array

if(matrix == NULL)
{
  // handle error
}


for(int i=0; i<N; i++)
{
  for(int j=0; j<N; j++)
  {
    printf("Value: %f", matrix[i][j]);
  }
}
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • IIRC the standard does not require the all-bits-zero memory pattern to correspond to zero (or any valid) floating point value. Though in practice this usually :-) works. – n. m. could be an AI May 07 '13 at 06:36
  • 1
    Thanks for the solution. What if I need N to be inputted by the user though? – stealthysnacks May 07 '13 at 06:40
  • @user2063561 That's not a problem, C supports variable length arrays so the above array pointer can be created with a variable size. – Lundin May 07 '13 at 08:01
-3

Hi I have this c++ file and it works well till the end with g++ compiler.

#include <cstdio>
#include <cstdlib>

using namespace std;

int main(){
    int N = 10;
    double **matrix = NULL;
    matrix = (double **)malloc(sizeof(double *) * N);   // N is the size of the square matrix

    for(int i=0; i<N; i++)
    {
        matrix[i] = (double *)malloc(sizeof(double)*N);
    }

    for(int i=0; i<N; i++)
    {
        for(int j=0; j<N; j++)
        {
            printf("Value: %f", matrix[i][j]);
        }
    }
}
hongtao
  • 406
  • 4
  • 7
  • 2
    why `using namespace std` ??? 1) this namespace wasn't using in your code 2) IT'S C QUESTION, NOT C++ !! – borisbn May 07 '13 at 05:59
  • @borisbn thank you. This is just my habit of coding c++... after all, you could always compile c in c++ way.. – hongtao May 07 '13 at 06:02
  • 1
    "you could always compile c in c++ way" - nope. C++ doesn't support dynamic arrays in stack - `int N = 42; int array[ N ];`. C++ doesn't support initializing structure fields by name. C++ doesn't support implicit casting from `void*` to other (as n.m. said in comments), etc. – borisbn May 07 '13 at 06:08
  • 1
    Why would you use malloc in C++ and not `new` (or a vector, or a smart pointer)? It doesn't matter, since this answer is off-topic and should be deleted. – Lundin May 07 '13 at 06:15
  • @borisbn int N=42; int array[N]; surely can work in c++. you could have a try with g++ :) BTW, would you kindly tell me what "initializing structure fields by name" means? – hongtao May 07 '13 at 06:27
  • 1
    @hongtao (1) AFAIK this is an extension of C++, that supports by g++, but doesn't supports by other (2) this: `struct struct_t struct_var = { .field1 = 42, .field10 = "abcde" };` – borisbn May 07 '13 at 06:59