ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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;
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.
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
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.
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.