LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-27-2008, 09:48 PM   #1
nanxy
LQ Newbie
 
Registered: Jul 2008
Posts: 16

Rep: Reputation: 0
Unhappy why segmentation fault?


HI~ GUYS I wrote a C program and I tried to compile it but it always remind me that there is a segmentation fault in line 49.Can anyone help me to find it out? thank you~


1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4
5 typedef struct _HEADER {
6
7 int num1;
8 int num2;
9 int num3;
10 int num4;
11
12 }HEADER;
13
14 void **Allocate2D(long int NBytes, int rows, int columns);
15 void readheader(HEADER *,FILE *);
16 void writeheader(HEADER *,FILE *);
17
18
19 int main(int argc,char *argv[])
20 {
21
22 short ****datatable;
23
24 int i,j;
25 HEADER header;
26
27 /*if(argc !=2){
28 printf("Cannot open the file for read\n");
29 }*/
30
31
32 FILE *fp1=fopen(argv[1],"r");
33 FILE *fp2=fopen("newdata.dat","w");
34
35 printf("The processing file is %s \n",argv[1]);
36
37
38 datatable = (short ****)Allocate2D(sizeof(short **),2,2);
39
40 for (i=0;i<2;i++){
41 for(j=0; j<2; j++){
42 datatable[i][j] = (short **)Allocate2D(sizeof(short),2,3);
43 }
44 }
45
46 readheader(&header,fp1);
47
48 for(i=0; i<2 ;i++){
49 for (j=0; j<4; j++)fread(&datatable[i][j][0][0],sizeof(short),6,fp1);
50 }
51 fclose( fp1 );
52
53 if ( fclose( fp1 ) == 0 ) 54 { printf("Success to close input file\n");
55 }
56
57
58 /* sprintf(error_msg,"File1 Error '%s'\n",argv[1]);
59 perror( error_msg );
60 exit(1);*/
61
62 writeheader(&header,fp2);
63
64 printf("Can we get here?\n");
65
66 for(i=0; i<2 ;i++){
67 for (j=0; j<4; j++)fwrite(&datatable[i][j][0][0],sizeof(short),6,fp2);
68 fclose(fp2);
69 }
70
71 if(ferror(fp2)) {
72 printf("File2 Error\n");
73 exit(1);
74 }
75 if ( fclose( fp2 ) == 0 )
76 { printf("Success to close output file\n");
77 }
78 return(0);
79 }
80
81 void readheader(HEADER *header,FILE *fp1)
82 {
83 printf("Here is the readheader function\n");
84 fread(&(header->num1),sizeof(int),1,fp1);
85 fread(&(header->num2),sizeof(header->num2),1,fp1);
86 fread(&(header->num3),sizeof(int),1,fp1);
87 fread(&(header->num4),sizeof(int),1,fp1);
88 }
89
90 void writeheader(HEADER *header,FILE *fp2)
91 {
92 printf("Here is the writeheader function\n");
93 fwrite(&(header->num1),sizeof(int),1,fp2);
94 fwrite(&(header->num2),sizeof(header->num2),1,fp2);
95 fwrite(&(header->num3),sizeof(header->num3),1,fp2);
96 fwrite(&(header->num4),sizeof(header->num4),1,fp2);
97 }
98
99
100 void **Allocate2D(long int NBytes, int rows, int columns)
101 {
102 void **pntr;
103 int i;

104
105 pntr = (void **)malloc(sizeof(void *)*rows);
106 pntr[0] = (void *)malloc(NBytes*rows*columns);
107 for(i=1; i<rows; i++)pntr[i] = pntr[i-1]+(columns*NBytes);
108 return pntr;
109 }
 
Old 07-27-2008, 10:34 PM   #2
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
Quote:
short ****datatable;
You are allocating memory incorrectly. Segfault happens because short** is larger (2x..4x, dependng on system) than short, so you can't assign allocated short** array to short**** variable - you'll easily go out of allocated memory bounds.
If you really need to construct 4D array this way, then that'll be something like this:
Code:
short**** construct_4D(int dimension1, int dimension2, int dimension3, int dimension4){
    short**** result;
    int i1, i2, i3, i4;
    result = (short****)malloc(sizeof(short***)*dimension1);
    for (i1 = 0; i1 < dimension1; i1++){
        result[i1] = (short***)malloc(sizeof(short**)*dimension2);
        for (i2 = 0; i2 < dimension2; i2++){
            result[i1][i2] = (short**)malloc(sizeof(short*)*dimension3);
            for (i3 = 0; i3 < dimension3; i3++){
                result[i1][i2][i3] = (short*)malloc(sizeof(short)*dimension4);
            }
        }         
    }
    return result;
}
But I recommend to use other techniques, since correctly freeing this monstrosity will be quite problematic:
Code:
void free_4D(short**** array, int dimension1, int dimension2, int dimension3){
    int i1, i2, i3;
    for (i1 = 0; i1 < dimension1; i1++){
        for (i2 = 0; i2 < dimension2; i2++){
            for (i3 = 0; i3 < dimension3; i3++)
                free(array[i1][i2][i3])
            free(array[i][j]);
        }         
        free(array[i]);
    }
    free(array);
}
Your best choice will be to allocate memory as single block and then access data using arithmetics.
Something like this:
Code:
struct array4d{
     int dimensions[4];
     short *data;
};

struct array4d* create_4d(int dimension1, int dimension2, int dimension3, int dimension 4){
    array4d *result;
    int dataSize;
    result = (array4d*)malloc(sizeof(array4d));
    result->dimensions[0] = dimension1;
    result->dimensions[1] = dimension2;
    result->dimensions[2] = dimesnions3;
    result->dimensions[3] = dimesnions4;
    dataSize = dimension1*dimension2*dimension3*dimensions4*sizeof(short);
    result->data = (short*)malloc(dataSize);
    return result;
}

void free_4d(struct array4d *array){
    free(array->data);
    free(array);    
}

int get_offset(struct array4d* array, int i1, int i2, int i3, int i4){
    return i4 + array->dimensions[3]*i3 + i2*array->dimensions[2]*array->dimensions[3] +
    i1 * array->dimensions[1]*array->dimensions[2]*array->dimensions[3];
}

short get_element(struct array4d* array, int i1, int i2, int i3, int i4){
    return array->data[get_offset(array, i1, i2, i3, i4)];
}

void put_element(struct array4d* array, short data, int i1, int i2, int i3, int i4){
    array->data[get_offset(array, i1, i2, i3, i4)] = data;
}
Or change the way your application works, and store data in other format, or use normal arrays, not dynamically allocated ones.

I recommend you to read some book about pointers, memory and C and read some real code examples. Also, you don't free memory in your program, which is a mistake.

Last edited by ErV; 07-27-2008 at 10:43 PM.
 
Old 07-28-2008, 02:30 PM   #3
jiml8
Senior Member
 
Registered: Sep 2003
Posts: 3,171

Rep: Reputation: 116Reputation: 116
Indirection gone wild!
 
Old 07-28-2008, 11:35 PM   #4
nanxy
LQ Newbie
 
Registered: Jul 2008
Posts: 16

Original Poster
Rep: Reputation: 0
what do u mean? please?
 
Old 07-29-2008, 02:23 AM   #5
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
Quote:
Originally Posted by jiml8 View Post
Indirection gone wild!
Well, nanxy wanted 4d array as "short****", so here is proper initialization for it.
I prefer OOP container classes or 1D arrays with methods to access them as N-dimensional data.

Quote:
Originally Posted by nanxy View Post
what do u mean? please?
The initialization function I've provided (the one that returns short****) is what you asked for, but not exactly what you need. Most people wouldn't use such constructs (dynamically allocated N-dimensional arrays represented by pointers), because freeing memory correctly can turn into mini-nightmare. IMO, the normal approach would be to write wrapper class/struct/functions (depends on language. For C++ it'll be template class, for C it'll be struct + bunch of functions) which uses 1D array for storing values and functions to access those values as if it was N-dimensional array. See second piece of code.

I have no idea where you might get basic knowledge of using 1D array for storing N-dimensional data, how N-dimensional arrays are stored in memory, etc. I've picked that quite some time ago on old 8bit computer, I don't know which books cover that now.

Last edited by ErV; 07-29-2008 at 02:26 AM.
 
Old 07-29-2008, 03:03 PM   #6
nanxy
LQ Newbie
 
Registered: Jul 2008
Posts: 16

Original Poster
Rep: Reputation: 0
Sorry , but is this reference right?


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

typedef struct _HEADER {

int num1;
int num2;
int num3;
int num4;

}HEADER;


void readheader(HEADER *,FILE *);
void writeheader(HEADER *,FILE *);
short**** construct_4D(int dimension1, int dimension2, int dimension3, int dimension4);

int main(int argc,char *argv[])
{



int i,j;
HEADER header;
short ****datatable;

datatable = (short ****)construct_4D(2,2,3,4);

/*if(argc !=2){
printf("Cannot open the file for read\n");
}*/


FILE *fp1=fopen(argv[1],"r");
FILE *fp2=fopen("newdata.dat","w");

printf("The processing file is %s \n",argv[1]);

for (i=0;i<2;i++){
for(j=0; j<2; j++){
datatable[i][j] = (short **)construct_4D(2,2,3,4);
}
}



readheader(&header,fp1);

for(i=0; i<2 ;i++){
for (j=0; j<4; j++)fread(&datatable[i][j][0][0],sizeof(short),6,fp1);
}
fclose( fp1 );

if ( fclose( fp1 ) == 0 )

{
printf("Success to close input file\n");
}

writeheader(&header,fp2);

printf("Can we get here?\n");


if(ferror(fp2)) {
printf("File2 Error\n");
exit(1);
}
if ( fclose( fp2 ) == 0 )
{ printf("Success to close output file\n");
}
return(0);
}


short**** construct_4D(int dimension1, int dimension2, int dimension3, int dimension4){
short**** result;
int i1, i2, i3;
result = (short****)malloc(sizeof(short***)*dimension1);
for (i1 = 0; i1 < dimension1; i1++){
result[i1] = (short***)malloc(sizeof(short**)*dimension2);
for (i2 = 0; i2 < dimension2; i2++){
result[i1][i2] = (short**)malloc(sizeof(short*)*dimension3);
for (i3 = 0; i3 < dimension3; i3++){
result[i1][i2][i3] = (short*)malloc(sizeof(short)*dimension4);
}
}
}
return result;
}
 
Old 07-29-2008, 03:15 PM   #7
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
Quote:
Originally Posted by nanxy View Post
Sorry , but is this reference right?
No, it isn't because you aren't freeing memory.

Quote:
Originally Posted by nanxy View Post
datatable[i][j] = (short **)construct_4D(2,2,3,4);
This makes no sense. construct_4D gives you fully initialized pointer to 4D array, and in this line you are obviously trying to make it 6d, making a lot memory leaks in process.

Read some books about C/memory functions.
 
Old 07-30-2008, 12:46 PM   #8
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,665
Blog Entries: 4

Rep: Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945
Also look for existing "C" libraries designed to manage 3-D and 4-D arrays!
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Segmentation fault cybil001 Programming 39 02-19-2007 10:01 AM
segmentation fault simasimon Slackware 4 05-09-2006 08:09 PM
yast segmentation fault, system freezing - nvidia driver at fault? BaltikaTroika SUSE / openSUSE 2 12-02-2005 09:34 AM
Segmentation fault, WHY?? eXor Slackware 8 07-20-2005 01:55 PM
Segmentation Fault (What is that?) jlacroix Fedora 6 11-17-2003 08:32 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:48 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration