0

Hi I am writing a program in C, however I am getting a segmentation fault upon running my program.

I am using gcc to compile and no warnings or errors are given at compilation time.

I tried using gdb to trace the origin of the segfault and it directs me to the line where I am assigning data values to my two dimensional array: array[row][column] = datavalue;

When I run my program stores 3 data values and then seg faults. It should store data on 424 rows by 117 columns, but consistently it seg faults after only storing 3 data values.

My code is as follows (with some details left out):

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

void allmem(float** fpdata,...);            // allocate memory header
void stored(float** fpdata,...);            // store data header
void countnumber(int* num1, int*num2,...);  // count header

int main()   // main() function
{
int numberofrows = 424; // number of rows
float** fpdata;         // two dimensional array fpdata of floats

allmem(fpdata,...);     // call allocate memory function
stored(fpdata,...);     // call function to store data
...
return 0;
} // main ()

// --------------stored() function---------------
void stored(float** fpreal,...) {

FILE *fp;                  // file pointer
float datavalue;           // variable to hold data values read
int row;
int column;

fp = fopen("c:/file.txt","r");

for(column = 0; column < 117; column++) {
  for(row = 0; row < 424; row++) {
    fscanf(fp, "%f,", &datavalue);
    fpdata[row][column] = datavalue;
  } // for
} // for  
fclose(fp);
} // stored()

// ----------allmem() function----------------
// function to allocate memory for two dimensional arrays
// I have hard coded the values of the array sizes in, but
// in my actual program they are calculated at run time based
// on the size of some input files and this is done in the 
// countnumber() function

void allmem(float** fpdata,...) {
int i = 0;
fpdata = (float**) malloc((424)*sizeof(float*));
fpdata2 = (float**) malloc((424)*sizeof(float*));
...
for (i = 0; i<424; i++) {
  fpdata[i] = (float*) malloc((117)*sizeof(float));
  fpdata2[i] = (float*) malloc((117)*sizeof(float));
} // for

} // allmem()
4
  • Are you checking to make sure that all of your calls to malloc return successfully? Commented Apr 2, 2011 at 1:17
  • You were right, my apologies. I deleted my answer. Commented Apr 2, 2011 at 1:28
  • yeah, i checked that there were no no null pointers returned, I am not running out of memory, I think I am just somehow writing to an allocated location of memory, but I don't know how this this happening. Commented Apr 2, 2011 at 1:32
  • thank you anyway for your help karlphillip Commented Apr 2, 2011 at 1:39

1 Answer 1

6

fpdata is passed by value instead of by pointer or by reference. That means that when the function returns from allmem, fpdata still points to the same thing it did before and the allocated memory is lost.

You'll want to call allmem(&fpdata,...);

And use a function signature of void allmem(float*** fpdata,...)

Then, in allmem, set *fpdata = (float**)...

And, of course, (*fpdata)[i] = (float*) malloc... inside the 'for' loop.

Edit:

I expect you'd do the same for fpdata2. But you shouldn't have to change anything in stored() (although it looks like you pass in fpreal but assign values to fpdata which is probably just a simplified code error?). The pointers passed to stored should be valid as they are. You're not trying to change the pointer in stored, just values in the memory that it points to.

Sign up to request clarification or add additional context in comments.

7 Comments

Hi, thank you JCooper, however I am still getting a segmentation fault after adding in your recommendations and the same thing is occurring with only a couple of data locations being written to before it seg faults. Perhaps you could be more explicit in all of the changes I would need to make, just so I can verify that I did make all necessary changes. Thank you
Hi JCooper, I think I just needed to also do (*fpreal)[row][columns] = datavalue in order to write to my array. I thought I declared the array as a double pointer, so really I just have a bunch of double pointers, so I should be able to pass fpdata since it is a pointer already?
You've declared a double pointer called fpdata. It initially points to garbage. You passed the value of that garbage to allmem. allmem created a new variable to hold that garbage. Then you set the value in that new variable to be a pointer to some memory. When the function returned, that newly created variable was tossed from the stack and all the allocated memory was lost.
Thank you JCooper, you really saved me so much time. I was also wondering if there was a better way for me to dynamically allocate a two dimensional array in C rather than the way that I chose, also, was choosing to pass it around to a bunch of different functions using this way a good method?
In C, it seems traditional to allocate a single, long block of memory with a single malloc() that is widthheight long. Then you just address it as array[rowwidth + column]. Typically, one would only allocate a pointer of pointers as you've done if they were going to have rows of different widths or they were going to be swapped around a lot.
|

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.