I keep running into a problem with reading values of a struct array, where I keep getting a segmentation fault. Here is the code:
int main()
{
/* Get PATH Environment Variable */
char *pathv[MAX_PATHS];
char cmd_line[MAX_ARGS];
struct command_t cmd[3]; //THIS IS THE STRUCT ARRAY
size_t len = 0;
/* Parse The Path */
ParsePath(pathv);
while(1) {
/* Print Continuous Prompt */
PrintPrompt();
/* Read Command Line & Parse It */
ReadCommand(cmd_line);
ParseCommand(cmd_line, cmd); //PASSING IT TO THIS METHOD
}
return 0;
}
int ParseCommand(char *buffer, struct command_t *cmd)
{
char *name = "Test";
cmd[0].name; //IF THIS IS COMMENTED OUT AND THE OTHER LINE AS WELL, PROGRAM RUNS
printf("%s\n", cmd[0].name); //FINE....THESE TWO LINES CAUSE SEG. FAULT
}
struct command_t {
char *name;
int argc;
char *argv[MAX_ARGS];
};
What am I doing wrong? Your help is greatly appreciated.
You never initialize cmd nor write any data. Accessed uninitialized data is undefined behavior in C so yes it is valid to crash. You need to write something into cmd[0].name before reading from it.
In C, when you declare a variable without assigning a value to it doesn't mean it is empty. It may point to memory garbage from stuff that was ran previously.
Your attempt to printf() whats in cmd[0].name without initializing it can be catastrophic.
You should initialize each variable in your struct before trying to access its value, or at least zero-fill everything in order to make it safe to read:
memset(cmd, 0, sizeof(*cmd) * 3);
Related
When running this program in Visual Studio, I receive an "Access Violation" error when the program reaches the memcpy function. No matter what size I make this buffer, it always throws this read access violation error. I've set breakpoints at the memcpy function and as soon as I continue the execution, it throws this error:
snip of error
char data[DATA_SIZE] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
#define DATA_SIZE 27136
void spawn(void * buffer, int length, char * key);
typedef struct {
int offset;
int length;
char key[4];
int gmh_offset;
int gpa_offset;
char payload[DATA_SIZE];
} phear;
extern char data[DATA_SIZE];
void start(HINSTANCE mhandle) {
phear * payload = (phear *)data;
char * buffer;
buffer = (char *)malloc(payload->length);
memcpy(buffer, payload->payload, payload->length);
/* execute our code */
spawn(buffer, payload->length, payload->key);
/* clean up after ourselves */
free(buffer);
}
There's several problems here:
data might not be correctly aligned for phear. See What is aligned memory allocation?
payload->length is a strict aliasing violation: this is defined as (*payload).length and the expression *payload accesses memory through an expression of type phear but there is no object of type phear at that location.
(If we ignore the above two problems for a moment) The memcpy reads out of bounds because sizeof data < sizeof(phear).
A simple solution would be to use extern phear data; instead of the char array. If you really want to use the char array then copy data in and out of it with memcpy instead of struct access.
I have tried solving an exercise where we have to return a struct containing the first whitespace-separated word and its length of a given string. Example: "Test string" returns {"Test", 4}.
To solve this problem I have implemented the following function:
struct string whitespace(char* s){
char* t = s;
size_t len = 0;
while(*t != ' '){
len++;
t++;
}
char out[len+1];
strncpy(out, s, len);
if(len>0){
out[len] = '\0';
}
//printf("%d\n",len);
struct string x = {out, len};
return x;
}
with the struct defined as follows:
struct string{
char* str;
size_t len;
};
If I run the following main function:
int main(){
char* s = "Test string";
struct string x = whitespace(s);
printf("(%s, %d)\n", x.str, x.len);
return 0;
}
I get this output:
(, 4)
where when I remove the comment //printf("%d\n",len); I get:
4
(Test, 4)
In fact, the string (Test, 4) is output whenever I print out a given variable in the function whitespace(char* s). Also when using different gcc optimization flags such as -O3 or -Ofast the result is correct even without the printing of the variables in the function.
Did I bump into some kind of undefined behavior? Can somebody explain what is happening here?
The struct you're returning includes a char *, which you point to the local variable out. That variable goes out of scope when the function returns, so dereferencing that pointer invokes undefined behavior.
Rather than using a VLA, declare out as a pointer and allocate memory for it to point to. Then you can safely set the struct member to that address and the memory will be good for the duration of the program.
char *out = malloc(len+1);
Also, be sure to free this memory before exiting your program.
I'm passing values beteween childs and need to store some values to later use.
the definitions and use in functions
char fouts[MAX_SIZE][10];
the function where i give the array the values:
void connect(char *nodo, char *out[], int nouts) {
(...)
for(i=0;i<nouts;i++) {
fouts[fnum][i] = out[i];
}
(...)
and the function where i'm trying to use them:
void disconnect(char *nodo, char *remover){
char *outs[10];
nouts = fnouts[getfnum];
int m =0;
for(i=0;i<nouts;i++) {
if(strcmp(fouts[getfnum][i],nodo) != 0) { outs[m] = fouts[getfnum][i]; m++ ; }
}
no matter what i did to try to fixm everytime it tries to execute this last for, it gives a segmentation fault.
have tried somethings (read fouts[getfnum][0] for example directly and gives a segmentaton fault, but fouts[getfnum] gives "trash")
check the value after it been atributed fouts[fnum][i] = out[i]; here and it checks out, so i guess that part is ok).
don't know if its something obvious or not, but any help?
You are mixing char and char*.
fouts[fnum][i] is a char
and
out[i] is a char pointer
So in this line
fouts[fnum][i] = out[i];
you assign a char pointer to a char which is illegal.
And in this line
if(strcmp(fouts[getfnum][i],nodo) != 0)
you pass a char (i.e. fouts[getfnum][i]) to strcmp.
That is not legal as strcmp expects a char*
From the posted code, it is hard to tell how to fix the problems. Maybe you just need:
char* fouts[MAX_SIZE][10];
while(!feof(fname))
{
fscanf(fname,"%c",buf);
printf("%c",*buf);
buf++;
}
When I use this code, the compiler gives me a segmentation fault(core dumped).
But instead of this if I use
int i = 0;
while(!feof(fname))
{
fscanf(fname,"%c",&buf[i]);
printf("%c",buf[i]);
i++;
}
This code runs fine, and the content of the file are read.
What am I doing wrong while incrementing the array pointer instead of using it as and array?
The whole code is
FILE *fname;
fname = fopen("input.txt", "r");
int i;
char *buf;
i=0;
while(!feof(fname))
{
fscanf(fname,"%c",buf);
printf("%c",*buf);
buf++;
}
fclose(fname);
char *buf;
This is a pointer and has no memory associated with it.
fscanf(fname,"%c",buf);
is attempting to place memory into this pointer. It needs to either be malloc'd, or defined as a char array that won't overflow from the fscanf() input.
perhaps:
#define MAX_STRING_SIZE 255
char buf[MAX_STRING_SIZE];
Additional Info edit
If you need a moving pointer, create a second one and use it:
#define MAX_STRING_SIZE 255
char buffer_memory[MAX_STRING_SIZE];
char *buf = buffer_memory;
...
fscanf(fname,"%c",buf);
printf("%c",*buf);
buf++;
Until you read in 255 character at which point bad things happen. If you don't know how big your file is beforehand (ftell()), then you will need to use a linked list system, a realloc() pattern, which is kinda icky, or a buffer that is guarenteed to be big enough to fit your file.
I can't return a pointer to a character array from a different file other than the main function. It always says "segmentation fault". But if I write the function in the same file as main, There is no problem.
/* this is in mainfunc.c file*/
int main()
{
char ch[5]={'a','b','c','d','\0'};
char *res=retchararray(ch);
printf("%s\n",res);/*I get segmentation fault only when I use this printf*/
}
/* this function is in other file newfile.c */
char *retchararray( char *p){
char *str;
str=p;
unsigned int len=strlen(p);
*(str+len)='e';
*(str+len+1)='\0';
return str;
}
I use netbeans on Mac OS to do C Programming.
Can some please tell me what is the problem? Or Am I doing some mistake here?
The function retchararray overflows your array. You use more memory than you have reserved.
This happens in *(str+len+1) = '\0' and causes the segfault.