Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
My program stores matrix in binary files, when I try to "load" them during the same use of the program, everything works well.
However, when I close the program and use it later, it's impossible to access to the same files and I get a Segmentation fault (core dumped) error.
Here's the function that "loads" the matrixes :
void Loading(int mat**){
char* name = malloc(sizeof(char)*20);
printf("Enter name of the file");
scanf("%s",name);
FILE* file=fopen(name,"rb");
if (file==NULL){
printf("error opening file");
exit(0);
}
fread(mat,sizeof(int)*M*M,1,file);
fclose(fichier);
}
where M is a constant.
Again it works perfectly when I store/load mutliple times during the same use of the program
sorry for the mistakes I am not an english speaker
As presented, the question is missing key elements to allow a full analysis, nor a complete answer. But with what is shown, here are some suggestions:
1) The reason(s) for your segmentation fault cannot be identified with absolute certainty because some of the pieces are missing from your post. However, given the fact that it works sometimes, and not others, suggests undefined behavior is playing a part. If I were to guess at the source of undefined behavior, it would be that you are passing around a double pointer variable int **mat, when only a single pointer variable int *mat is necessary (see prototype of fread() below.), further leading me to believe that memory for mat has not been correctly created. I suggest changing:
void Loading(int mat**) // double pointer is not needed here
to
void Loading(unsigned int mat*) //and memory allocation method adjusted accordingly.
(See reason for unsigned in 3) below.)
2) The prototype for the function fread() is:
size_t fread (void *Buffer, size_t Element_Size, size_t Number_of_Elements, FILE *Stream);
In your call:
fread(mat,sizeof(int)*M*M,1,file);
Arguments 2 & 3 appear to be reversed. It should probably be written:
fread(mat, sizeof(unsigned int), M*M, file);
3) Why unsigned int verses int when working with binary data?:
Your post is not explicit on how the data is written to the file, or exactly what format it is in, but generally, when working with binary data, it is better to stick with unsigned types for the reasons listed here.
You have a pointer to your buffer for matrix int **mat.
The problem is, that this doesn't point to single continuous place in memory.
int mat** is a pointer to array of pointers to int. This is a place in memory that should contain more pointers one stored after another. Each of them (int*) then should point into different arrays, that would finally contain array of integers.
Basically you use command fread to write whole data into the array of pointers. Maybe you don't have enough space to store your data at all. Even if you would, you need another kind of pointer.
If you have one continuous array, you could point to it using int *. Then you would pick some element by calculating an index.
int *mtx = (int*) malloc(M*M*sizeof(int);
int x = 2, y = 3;
int index = y*M+x;
mtx[index] = 123; // write to matrix coordinates 2,3
You could use fread with this kind of buffer with no problem, just check how are matrix elements indexed in your input file, maybe the x,y is swapped.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am writing a function in C. What I found is that when I debug in gdb, I found a pointer "result" has the same address with another pointer before "result" was declared. Part of my code:
char* stringSum(char* x, char* y){
puts(x);
puts(y);
printf("\n");
int lengthx=strlen(x);
int lengthy=strlen(y);
int lengths=MIN(lengthx,lengthy);
int lengthl=MAX(lengthx,lengthy);
char* s=((lengthx<=lengthy)?x:y);
char* l=((lengthx>lengthy)?x:y);
int returnSize=MAX(lengthx, lengthy)+2;//-----I could print result now
printf("before, short is : ");puts(s);
char* result=malloc(sizeof(char)*returnSize);//-----but result is allocated now
printf("after allocate memory for result, short is: ");puts(s);//---s is changed!
result[returnSize-1]='\0';
......
}
This function get the sum of two numbers (in string) so that I could calculate the sum of two large numbers. In gdb: I got this weird problem:
My problems are in red and yellow rectangles
(When debug in gdb) Before char* result=malloc(sizeof(char)*returnSize); I print s and result (so now it haven't been declared yet) and got
(gdb) print s
$5 = 0x61f950 "6597242170048699800240000000000"
(gdb) print result
$6 = 0x61f950 "6597242170048699800240000000000"
I couldn't understand that since how could an undeclared pointer points to an existing address? (This function is called by another function with a very large number of x and y (in string). If I changed them to relatively small values I will always get the right answer. What's more, if I create a new .c file and only have this function and main function, I will not have that problem anymore even with a large value.)
My second problem is that I have printed s twice and I found the second time I print (after declare the pointer result) s is changed! (Similar to the first problem, if I choose smaller values for x and y or create a new .c file, I will not have the same problem.)
I guess I have some problem with malloc but after search online I haven't find any useful resources will could help me solve the problem. Do I have the problem about memory management?
You have at least two serious problems with your code.
The first problem is that you never free what you malloc, creating sizeable memory leaks at each recursive call.
The second problem is that you are trying to assign strings, which doesn't have the effect you hope for.
Here is an example of what you do (comments mine):
// allocate some memory and assign its address to abcd
char* abcd=malloc(sizeof(char)*returnSize);
// throw it away by assigning a different value to abcd
abcd=karatsuba(stringSum(a,b),stringSum(c,d));
// then assign yet another different value to abcd
abcd=stringSubstract(abcd,ac);
// and another one
abcd=stringSubstract(abcd,bd);//ab+cd
// Code below overflows, because memory abcd is pointing to is
// not the original block allocated for it (you threw it away).
// It is a block allocated and returned by stringSubstract.
// Its length is not necessarily sufficient to accommodate all
// the data you are trying to stuff in it.
int labcd=strlen(abcd);
for(i=0;i<=(ns/2-1);i++){
abcd[labcd+i]='0';
}
abcd[lac+i]='\0';
You can verify that this is the case by running your program under valgrind. You will get error messages that indicate a buffer overflow just before the mysterious shortening of s. It all goes downhill from there.
In order to fix the problem, you may want to use strcpy instead of pointer assignment. Another way to fix it would be ditching the abcd = malloc(...) lines in the beginning of the function, and using realloc to make sure they have the allocations have enough size.
In addition you definitely want to fix the memory leaks. You need to call free for each variable you malloc after you're done with it. If you are returning a malloced variable, the caller needs to free it after using it.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I know that we cannot dereference a void pointer until and unless we typecast it.
void *ptr = call_a_function();
printf("%d",*(int *)ptr);
This informs the datatype of element(in this case its integer) to the compiler so that it can dereference the amount of space required for it(in this case its 4 bytes).
Suppose I dont know the final datatype, however I know the size of datatype. Can I still dereference it using only the size(4 bytes) and not the datatype(not using int)??
In other words is there a way to tell the compiler how many bytes of memory to read by providing the number of bytes to extract and not the datatype??
EDIT -
I needed to swap the contents of two void * pointers.
Got influenced by the regular way of swapping two values i.e storing the value of one pointer in a temporary variable and then proceed with swapping.
Was trying to attempt the same thing without knowing the datatype but only its size( since the function with this swap code accepts size of variable as one parameter ). However after reading the answers and comments, got to realize that I really dont need to dereference it. Probably memcpy is the correct way to go.
Suppose I dont know the final datatype, however I know the size of datatype. Can I still dereference it using only the size(4 bytes) and not the datatype(not using int)??
Since you cannot deduce or assume the data type, you can't dereference the pointer once to get the complete object. However, you can extract each byte and use it anyway you want.
void *ptr = call_a_function();
unsigned char* cptr = (unsigned char*)ptr;
for (int i = 0; i < num_bytes; ++i )
{
unsigned char c = cptr[i];
// Use c
}
In this case, the whole is not the sum of its parts. Casting not only provides the compiler with the size of the data but also how that data is to be interpreted. Suppose you get 4 bytes, this could be a string of three characters with a NULL byte or a signed integer, which could be encoded in big-endian or little-endian depending on the platform. So knowing the size is not sufficient to properly handle the data even if you could tell the compiler how many bytes to read/dereference.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a file which looks like following:
ATOM HIS
ATOM TRP
ATOM PHE
I want to print the first column, following is my C-code:
#include<stdio.h>
#includ<stdlib.h>
void main
{
FILE *fp;
fp=fopen("xyz","r");
char *atm,*res;
char buff[200];
while(fgets(buff,sizeof (buff),fp)!=NULL){
i++;
}
rewind(fp);
atm=(char*)malloc(i * sizeof (char*));
res=(char*)malloc(i * sizeof (char*));
while(fgets(buff,sizeof (buff),fp)!=NULL){
fscanf(fp,"%s %s",&atm[i],&res[i]);
i++;
}
for(j=0;j<i;j++){
printf("%s\n",atm);
}
I would expect the following output:
ATOM
ATOM
ATOM
But it doesn't compile and says that:
warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’
hence in printf statement I have added & to atm (i.e &atm instead of atm). In this case the code compiles well but gives the following output:
AAAAAAAAAAAAAAAATOM
AAAAAAAAAATOM
AAAAAAAATOM
I will appreciate any suggestion regarding this.
First of all,
atm=(char*)malloc(sizeof (char*));
does not do what you think it does. It only allocates a memory enough o hold a char *, that's also wrongly.
You need to allocate a size of n * sizeof(char), where, n == number of chars. Now, sizeof(char) == 1 being guaranteed by C standard, your statement can be reduced to
atm = malloc(requiredsize);
res= malloc(requiredsize);
After that, you should check for the success of malloc() call to prevent UB from accessing NULL pointer.
But then, you'll be overwriting atm and res in every call to fgets() and fscanf(). You seem to need an array of pointers, not a simple pointer to get the job done.
If atm and res are pointers to arrays of char *, which seems like the intention, then they should be declared as such:
char **atm,**res;
You then need to allocate storage for each string, as well as the array as a whole:
while(fgets(buff,sizeof (buff),fp)!=NULL){
atm[i] = malloc(200); // choose a suitable maximum size
res[i] = malloc(200);
fscanf(fp,"%s %s",atm[i],res[i]);
i++;
}
This much more closely matches your intention - I think.
It's not particularly good practice, however. Using fscanf with %s, there is no guarantee that the string you read won't be longer than what you've allocated (I think you can use a width specifier to limit what it reads, eg %100s, but that limits how much is read as well as how much is stored). You should also check the return from malloc in each case to make sure it was successful.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
In my code FILES is struct.
typedef struct {
char name[64];
char filename[64];
long size; // file size
long loaded; // after load of kernel loaded should be same value as size
char * program;
} FILES;
files is array of type FILES.
FILES files[MAX_KERNELS_COUNT];
in function loadKernels I would like to access member of the array files via pointer.
bool loadKernels(const char * path, FILES * files, int count)
{
...
size = strlen(files[c].program);
printf("\n%ld\n",size);
size = sizeof(files[c].program);
printf("\n%ld\n",size);
...
}
I have problem there on the line with files[c].program . I know that I must access files like a pointer but how to do it correctly to obtain the length of the C string? I know something like (*files)[c].program is wrong.
files is an array of FILES.
files[c] is thus of type FILES
files[c].program is thus of type char *.
so strlen(files[c].program) should give you what you want, i.e. the length of the string (as opposed to the size of the pointer). Note strlen will exclude the terminating NUL, i.e. the size of the string will be one byte longer.
size = strlen(files[c].program);
printf("\n%ld\n",size);
size = sizeof(files[c].program); //<-- Here you are using the sizeof. change this into strlen
printf("\n%ld\n",size);
Sizeof gives you sizeof the given variable. It will not give you the string length.
I have problem there on the line with files[c].program . I know that I
must access files like a pointer but how to do it correctly to obtain
the length of the C string? I know something like (*files)[c].program
is wrong.
There is no string
program is a pointer to somewhere outside the array.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Could someone please tell me about what is wrong with the code? Sorry if I'm new at this but I am trying to get this right for a long time. I am trying to get input from the user and then print the values. The following code is just an example.
I try to run the code but I get run-time errors. Can anyone pls help?
#include <stdio.h>
#include <stdlib.h>
typedef struct poly
{
int kill;
float bill;
char katana[50];
} koly;
typedef koly* terma;
int main()
{
int count = 0;
terma ren;
ren = (terma)malloc(sizeof(koly));
ren = (terma)realloc(6*sizeof(koly));
printf("We can store now:\n\n");
while(++count<= 2)
{
scanf("%d",ren->kill);
scanf("%f",ren->bill);
scanf("%s",ren->katana);
}
while(++count<= 2)
{
printf("\n%d\n",ren->kill);
printf("\n%f\n",ren->bill);
printf("\n%s\n",ren->katana);
}
}
About your error:
scanf("%d",ren->kill);
scanf("%f",ren->bill);
These should be pointers, so the corrected version is:
scanf("%d",&ren->kill);
scanf("%f",&ren->bill);
Also, realloc expects 2 arguments unlike malloc. The first should be a pointer to the address you are reallocing, and the second should be the new size. So:
ren = realloc(ren, 6 * sizeof(koly));
I have two other things to say about your code. First: it is unnecessary to cast the return value of malloc in C (and is frowned upon). Also, NEVER use scanf with the "%s" format specifier. This is extremely insecure and can easily lead to crashes and worse. The best method is to use fgets, so scanf("%s",ren->katana); would become this:
fgets(ren->katana, sizeof(ren->katana), stdin);
Edit:
Here is my explanation for why casting the return value of malloc/realloc should be avoided:
It's not really because it's wrong; it's because it is bad practice to do so in C. Since a void* type is automatically converted to any pointer type, the typecasting is superfluous, the code is less readable (IMO), and it makes changes more difficult. For example, take your case:
ren = (terma)malloc(sizeof(koly));
I personally would rewrite this line like so:
ren = malloc(sizeof(*ren));
This allows for easily changing the type of ren. If ren were changed to another data type (such as int* or struct sockaddr_in* or anything else), it would automatically work. You wouldn't need to change the type in the cast or the type in the sizeof(). Both will automatically work for the new type. For arrays, it works the same:
int* myArr = malloc(42 * sizeof(*myArr));
If I instead wanted myArr to hold an array of 42 floats, the change is simple:
float* myArr = malloc(42 * sizeof(*myArr));
Note: In C++, the typecast is required as it doesn't automatically convert void* to other pointer types, but you really shouldn't be using malloc et al in C++ anyways when you have new (plus this is a C question, not C++).
void *realloc(void *ptr, size_t size);
realloc takes two arguments, the prototype is as above, what you have missed in your code is to give the pointer for which you want to reallocate the memory.
you have to use, ren = (terma)realloc( rem, 6*sizeof(koly));
and another error is you have missed & operator in scanf function, it should be, scanf("%d",&ren->kill);
And its not the run time error, did you get the code compiled correctly...?
Realloc() takes two arguments. how does it even compiled?
ren = (terma)realloc(ren,6*sizeof(koly));
You also need scanf corrected:
scanf("%d",&ren->kill);
scanf("%f",&ren->bill);
But just word of caution: You are over-writing your only one object.