why does this simple strcpy(...) cause a segmentation fault? [duplicate] - c

This question already has answers here:
Segmentation Fault in strcpy()
(3 answers)
Closed 8 years ago.
I'm not understanding something simple.
I have this sample code:
typedef struct {
char* fname;
} PersonType;
int main() {
PersonType *p;
p = (PersonType *)malloc(sizeof(PersonType));
char * name = "Robert";
/* this next line causes a segmentation fault */
strcpy(p->fname, name);
printf("name: %s\n", p->fname);
}
Why is there a segmentation fault at the 'strcpy'? What am I doing wrong?
Any help is greatly appreciate, thanks!
Rob

Although you allocated space for the structure, you've neither allocated space for the string nor initialized the pointer in the structure. You need to use something like:
if (p != 0)
{
if ((p->fname = malloc(strlen(name) + 1)) != 0)
strcpy(p->fname, name);
else
free(p); // Report error too?
}
Note that this checks the results of the memory allocation. I'm not fussed about whether you cast the return type for malloc(); other people are.

Your PersonType struct contains a pointer to a string that you are never allocating, nor assigning. So fname is an uninitialized pointer that you are attempting to write to. You need to allocate a buffer for fname.
int main() {
PersonType *p;
p = (PersonType *)malloc(sizeof(PersonType));
p->fname = malloc(sizeof(char)*7);
char * name = "Robert";
Either that or make fname a char array so that your struct will contain a buffer within itself.

fname is not initialized to anything. strcpy will continue to read starting at the location fname points to until it encounters \0.
Either make fname an array, and initialize it. Or allocate fname and initialize it.

Related

strcpy pass initialized null pointer c [duplicate]

This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed 6 years ago.
I'm trying out the following code:
int main()
{
char *yo = "yo";
char *whaddup = NULL;
strcpy(whaddup,yo);
}
and I get a segfault. Complete C noob here - other places say I should initialize whaddup as an array. Why can't I pass in a pointer to null?
Just any strcpy documentation will tell you that the destination string should be a char array large enough to hold the string and the NUL terminator.
So what you need is something like
char* yo = "yo";
char* whaddup = malloc(strlen(yo)+1);
strcpy(whaddup, yo);
Or alternatively you could use strdup function which does this for you, but it's not standard as it's POSIX only.
You have to either declare whaddup as a character array or ideally allocate space for it with malloc.
int main()
{
char *yo = "yo";
char *whaddup = malloc(sizeof(char) * 8); // buffer for 8 characters
strcpy(whaddup,yo);
}
By initializing whaddup to NULL you are not giving it any space in memory, so even copying one character into it will result in a segmentation fault.
You can pass in a pointer to null, but you can not copy string from pointer to null.
The function char* strcpy(char* dest, const char* src) is copy string from address src to address dest, your dest is null.

Segmentation fault when using strcpy to copy a "string" into a struct member char* [duplicate]

This question already has answers here:
Segmentation Fault in strcpy()
(3 answers)
Closed 8 years ago.
I have a pointer to my struct gsa_sentence which has a struct member of type char* called untouched_sentence.
My goal is to copy a line from a file, into this struct variable using strcpy, but I am getting a segmentation fault on the strcpy function call.
structure:
typedef struct gsa_sentence{
char *untouched_sentence;
char *sentence_id;
char mode;
int fix;
int sv_1;
int sv_2;
int sv_3;
int sv_4;
int sv_5;
int sv_6;
int sv_7;
int sv_8;
int sv_9;
int sv_10;
int sv_11;
int sv_12;
int pdop;
int hdop;
int vdop;
}gsa_sentence;
strcpy call:
gsa_sentence* gsa;
gsa = malloc(sizeof(gsa_sentence));
printf("%s", line);
if(gsa != NULL){
strncpy(gsa->untouched_sentence, line, strlen(line));
printf("%s", gsa->untouched_sentence);
}
I have used strcpy elsewhere in my code and it works fine, I cannot figure out what is going on.
The gdb debugger says it's definately on the strcpy function call
Strcpy is attempting to copy characters into an uninitialized character buffer. You'll want to malloc space for untouched sentence," as well, or reassign untouched sentence to the memory address of line.
Alternatively, you could change the definition of the struct to include allocated memory by default:
typedef struct gsa_sentence{
char untouched_sentence[50];
char sentence_id[50];
...
You need to allocate memory for gsa->untouched_sentence before copying data. You are only allocating memory for the structure itself.
You have to allocate memory to gsa->untouched_sentence
gsa->untouched_sentence = malloc ( strlen ( line ) + 1 );
You must allocate space for your string: all characters, plus delimiter.
malloc (sizeof (gsa)) does NOT do this: "sizeof (gsa)" just returns enough for a pointer - not your entire string.
'malloc (sizeof (gsa_sentence))or 'malloc (sizeof (gsa_sentence)+1) would be better. But I'm not sure that's what you want, either.

String copy(strcpy)

I have the following code.
#include <string.h>
#include <stdio.h>
int main()
{
char * l;
*l = 'c';
*(l+1) = 'g';
*(l+2) = '\0';
char *second;
strcpy(second, l);
printf("string: %s\n", second);
}
When I run it is says:
The output says "Segmentation fault"....any suggestions??
Thanks
l is an uninitialized pointer; you can't dereference it. You should allocate enough space to write its contents (statically (1) or dynamically (2)).
char l[3]; /* (1) */
#include <stdlib.h>
char *l = malloc(3); /* (2) */
It is the same error with strcpy: second is an unitialized pointer, you can't write into it.
You will learn to despise the Segmentation Fault error...
It's usually called when you try to access memory that is not yours. Most common occurrence would be when you try to access an array index that is out of bounds.
char *l just creates a pointer to a char. What you want is a string, which in C is defined as an array of chars. So when you try to access the next location in memory of whatever l is pointing to (which will probably just be garbage), you're going to access memory that isn't yours, thus Segmentation Fault
You could get memory with malloc or point the pointer to an already existing variable.
char word[3];
char *l;
l = word;
Now you can do such assignments:
*l = 'c';
*(l+1) = 'g';
*(l+2) = '\0';
but now that you want to copy it to another pointer, this pointer must be pointing to another string or you should allocate memory for it.
char *pointer_to_second;
char second[3];
pointer_to_second = second;
or if you prefer to get dynamic memory, change the 3 lines above be this one bellow:
char *pointer_to_second = malloc(sizeof(char) * 3);
after that you can do what you wanted:
strcpy(pointer_to_second, l);
But remember, if you are using a C compiler you must declare all variables at the beggining, otherwise you will get an error. If you are using a C++ compiler you won't have to concern about it.
Segmentation fault happens when you try to access a field that doesn't belong to your vector. For example, if you try this:
printf("The value in position 3 of my pointer is %c\n", *(l + 3));
You will probably get an error, because you pointer have 3 positions and you are trying to acess the 4th one.

Segmentation fault while using malloc with char pointers

I am new to C and learning structs. I am trying to malloc a char pointer with size 30 but it is giving a segmentation fault(core dump). I searched it on the internet & SO but am not able to resolve this. Any help will be much appreciated.
Probably I am accessing the char* member of the struct incorrectly ?
typedef struct{
int x;
int y;
char *f;
char *l;
}str;
void create_mall();
void create_mall() //Malloc the struct
{
str *p;
p->f = (char*)malloc(sizeof(char)*30); // segmentation fault here
p->l = (char*)malloc(sizeof(char)*30);
printf("Enter the user ID:");
scanf("%d",&p->x);
printf("\nEnter the phone number:");
scanf("%d",&p->y);
printf("\nEnter the First name:");
scanf("%29s",p->f);
printf("\nEnter the Last name:");
scanf("%29s",p->l);
printf("\nEntered values are: %d %d %s %s\n",p->x,p->y,p->f,p->l);
}
int main(void)
{
create_mall();
return 0;
}
Here's your problem:
str *p;
You've declared a pointer to an instance of str, but you haven't initialized it with a value. You either need to move this variable to the stack:
str p;
...or malloc some memory for it first:
str *p = (str*)malloc(sizeof(str));
You never allocated space for the struct itself, only a pointer to it.
Try something like:
str *p = malloc(sizeof(str));
As many people have pointed out, you need to allocate memory for that str struct, before writing the fields of it.
The best way to do so in C is:
p = malloc(sizeof *p);
This has the following advantages:
No cast, since no cast is needed in C and having a cast can hide actual errors.
No duplication of type information, by using the sizeof operator to compute how much storage is needed for the value p points at.
When you then allocate the string space, you can simplify it to:
p->f = malloc(30);
Because:
No cast, for the very same reason.
C guarantees that sizeof (char) is always 1, so using it like you did adds nothing, 1 * 30 is always just 30.
Last, you should always check the return value of malloc() before using it, since it can fail and return NULL.
Check for NULL values in return of malloc() function.
Also str *p; < is not initialised.
initialize p as str *p = malloc(sizeof(str));
The problem lies here.
str *p; ---> Problem Line 1<br>
p->f = (char*)malloc(sizeof(char)*30); ----> Problem Line2
p->l = (char*)malloc(sizeof(char)*30);
You have declared a pointer p of type str.
Problem 1:
You have not initialized this pointer to NULL. Thus, p can point to anything.
Problem 2:
Since p is an uninitialized pointer, p->f can point anywhere which is causing the segfault.
Below is the correct way
str *p = NULL;
p = malloc(sizeof(str));
// Check p for NULL
memset(p, 0, sizeof(str));
Now you have an initialized memory pointed by p. You are now free to use it as you want.

What's wrong with strcpy()? (Segmentation fault) [duplicate]

This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed 3 years ago.
What is wrong with strcpy() in this code?
void process_filedata(char *filename)
{
void* content;
const char * buffer;
char * temp;
char * row;
char * col;
int lsize,buflen,tmp,num_scan; //num_scan - number of characters scanned
int m=0,p=0,d=0,j=0; //m - machine, p - phase, d- delimiter, j - job
FILE *file_pointer = fopen("machinetimesnew.csv","r");
if(file_pointer == NULL)
{
error_flag = print_error("Error opening file");
if(error_flag) exit(1);
}
fseek(file_pointer, 0 ,SEEK_END);
lsize = ftell(file_pointer);
buflen = lsize;
rewind(file_pointer);
// content = (char*) malloc(sizeof(char)*lsize);
fread(content,1,lsize,file_pointer);
buffer = (const char*) content;
strcpy(temp,buffer);
row = strtok(temp,"\n");
...............
...............
I am getting a segmentation fault..
You're not allocating any space for temp. It's a wild pointer.
There are actually three segmentation faults here:
fread(content,1,lsize,file_pointer);
strcpy(temp,buffer);
row = strtok(temp,"\n");
The first one is fread() which is attempting to write to memory that does not yet exist as far as your process is concerned.
The second one is strcpy(), (expounding on the first) you are attempting to copy to a pointer that points to nothing. No memory (other than the pointer reference itself) has been allocated for temp, statically or dynamically.
Fix this via changing temp to look like this (allocating it statically):
char temp[1024];
Or use malloc() to dynamically allocate memory for it (as well as your other pointers, so they actually point to something), likewise for content. If you know the needed buffer size at compile time, use static allocation. If not, use malloc(). 'Knowing' is the subject of another question.
The third one is strtok() , which is going to modify temp en situ (in place), which it obviously can not do, since temp was never allocated. In any event, don't expect temp to be the same once strtok() is done with it. By the name of the variable, I assume you know that.
Also, Initializing a pointer is not the same thing as allocating memory for it:
char *temp = NULL; // temp is initialized
char *temp = (char *) malloc(size); // temp is allocated if malloc returns agreeably, cast return to not break c++
Finally, please get in the habit of using strncpy() over strcpy(), its much safer.
Nothing's wrong with strcpy. You haven't initialised temp.
There's yet another mistake. fread does not add a nul character to the end of the buffer. That's because it only deals with arrays of bytes, not nul-terminated strings. So you need to do something like this:
content = malloc(lsize + 1);
fread(content,1,lsize,file_pointer);
content[lsize] = 0;
temp = malloc(lsize + 1);
strcpy(temp, content);
or this:
content = malloc(lsize);
fread(content,1,lsize,file_pointer);
temp = malloc(lsize + 1);
memcpy(temp, content, lsize);
temp[lsize] = 0;
(Also, in real code you should check the results of fread and malloc.)
you didn't allocate memory for temp
char * temp hasn't been initialized and you consequently haven't allocated any memory for it.
try:
temp = (char *)malloc(SIZE);
where SIZE is however much memory you want to allocate for temp
This piece of code intrigues me:
if(file_pointer == NULL)
{
error_flag = print_error("Error opening file");
if(error_flag) exit(1);
}
Shouldn't you exit unconditionally if the file_pointer is NULL?

Resources