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.
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 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.
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
char *variable;
printf("write variable");
scanf("%s",&variable);
I tried this part of code for get a char variable from input but it doesn't work. I don't know how to get it, can I have some tips?
Ps: Thanks for the help, and sorry for the basic question
There are two problems here.
First, the %s format specifier to scanf expects a char * argument pointing to a char array (either dynamically or statically allocated). You're passing it a char **, which is an incompatible type. Remove the address-of operator & to pass the correct type:
scanf("%s",variable);
Second, even with this fix, variable is uninitialized. That means that scanf will attempt to write to an invalid memory address. You need to either declare variable as an array:
char variable[50];
Or dynamically allocate memory for it:
char *variable = malloc(50);
You'll also need to specify a field width in the scanf specifier so it knows the maximum number of characters it can read:
scanf("%49s",variable);
Note that the field width is one less than the size of the array to leave room for the terminating null byte.
You've used the & operator in scanf(it is used mostly), but for an string or array this does not work. Actually an array name is a pointer to first character of character array that mean it is the address of first character in character array. Now when you use & operator this passes address of address to first character of array, while required argument is of type char* and you're passing char**. Simply use as follow:
scanf("%s", mystring); // Good and works good
scanf("%s", &mystring); //bad and does not works
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 this two arrays, codeblocks doesn't give me any build error but whenever I run it, it gives "Segmention fault" and it shuts the program down I've debugged it and found out I can't change values from names1 this way but changing names2 this way works just fine, is there a way to make this work? If yes how do I make troca work for names1?
void troca(char* frase){
unsigned i=0;
while(*(frase+i)!='\0') {
if(*(frase+i)=='O') {
*(frase+i)='0';
}
i++;
}
}
int main(){
char *names1[]={"JOAO","MANUEL","ROBERTO","ZE"};
char names2[][51]={"JOAO","MANUEL","ROBERTO","ZE"};
unsigned i;
for(i=0;i<4;i++) {
troca(names2[i]);
}
return 0;
}
The difference is:
names1 is declared simply as an array of string pointers without other defined characteristics. Using string literals here will put the string literals into a section in your executable file which is read-only, because the compiler can this way re-use them. For example, when you use char* a = "abc"; char* b = "abc"; then most likely a and b will have equal memory addresses as values. This means you can't modify them, so you get a "Segmentation fault" (another name for the same error is "Access Violation").
names2 is declared as an array of arrays of chars. Assigning a string literal there will copy the data of the strings into the array, and since there is no const thing in play in your code, the array has to be mutable, so in turn your strings stored in the char arrays are mutable as well.
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 7 years ago.
Improve this question
my program
#include<stdio.h>
#include<conio.h>
char* mystrcat(char* , char* );\\ function declared as global
main()
{
char dest[50]="hello"; \\destination string
char src[50]="readers"; \\source string
clrscr();
mystrcat(dest,src);\\function calling but does not have receiving array
puts("after concatenation"); \\ of strings
puts(dest);\\shows "helloreaders"<-- how?
getch();
return 0;
}
char* mystrcat(char* des, char *sr)\\for concatenating two strings
{
int i=0,j=0;
while(des[i]!='\0')
{ i++;}
while(sr[j]!='\0')
{
des[i]=sr[j];
i++;j++;
}
des[i]='\0';
puts(sr);\\"readers"
puts(des);\\"helloreaders"
return sr;\\returning source string
}
output:
readers
helloreaders
after concatenating:
helloreaders
I am returning only source string from mystrcat(). But how compiler knows the modified destination string? Since I declare the function globally the compiler knows the modified string?
It is not because of return sr, rather it is because char* mystrcat(char* des, char *sr) modified its argument ( des ). Even if you change the return value to just an int, the result will be same. The reason is when you pass a char[] variable to a function, you just pass a pointer, anything you did inside the function to the variable will be reflected to the caller.
When you called function
mystrcat(dest,src);\\function calling but does not have receiving array
you passed as arguments two arrays that are implicitly converted to pointers to first elements of each array.
So inside the function you deal with addresses of the memory extents occupied by the arrays. And you write in the memory occupied by the destination array elements of the source array
while(sr[j]!='\0')
{
des[i]=sr[j];
i++;j++;
}
des[i]='\0';
because des and sr hold addresses of first elements of the arrays.
So the memory occupied by array dest was overwritten.
You are giving mystrcat() a pointer to dest and when it writes through that pointer, it changes dest directly. It doesn't matter what the function returns. des[] in mystrcat() is not a copy of dest[] in the main program, it's the same thing.
because parameters you pass to the function are points,arrays they point to are changed, but these points are not changed