SIGSEV on strcpy to a char pointer [duplicate] - c

This question already has answers here:
SIGSEV on strcmp of memset string
(3 answers)
Closed 3 years ago.
Why do i get a crash on strcpy even. I tried appending a 0,\0,\n using sprintf and check in gdb that its appended correctly but still i get a crash.
With malloc i dont get a crash, but somebody told me that malloc is not necessary in this case.
include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_LINE_SIZE 10
int main()
{
char* str[100];
int strCount=0;
char cCmd[] = "<some command>|awk '{print $1}'";
FILE *fp;
fp = popen(cCmd,"r");
if(cCmd != NULL)
{
char line[MAX_LINE_SIZE];
while (fgets(line, sizeof(line), fp) != NULL )
{
//str[strCount]=malloc(MAX_LINE_SIZE);
//sprintf(line,"%s%c",line,'\0'); -- even with appending a null character at the end it doesnt work
strcpy(str[strCount],line);
//strip(str[strCount]);
(strCount)++;
}
}
return 0;
}

The problem is in this statement strcpy(str[strCount],line)
char *str[100]; declares an array of 100 uninitialized pointers whereby each pointer needs to be allocated memory explicitly.
When you run str[strCount]=malloc(MAX_LINE_SIZE); statement, you are actually allocating memory for invidual pointers which is further used by strcpy to copy string.
When you are not using malloc, its an uninitialized pointer (having no allocated memory) causing strcpy to fail as you are coping in memory that may not belong to you or may not exist at all.

Related

Getting a segmentation fault but cannot see error? [duplicate]

This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed 4 years ago.
Here is a simple program that is a function which checks for the character 'a' within a string, then returns the character if found, and NULL if it is not found. I am not really sure if it is the function or the call of the function itself, here is the code.
#include <stdio.h>
char *find_char(char *str, char character);
int main(){
char *str;
printf("str\n");
scanf("%s", str);
printf("%c",*find_char(str,'a'));
return 0;
}
char *find_char(char *str, char character){
char *pstr = str;
while(*pstr!='\0' && *pstr!=character){
pstr++;}
if (*pstr!=character)
return NULL;
else
return pstr;
}
Your problem basically lies in these two lines, the first and third code line of your main function:
char *str; // Create pointer, pointing to ***arbitrary*** memory.
scanf("%s", str); // Write to that memory, undefined behaviour.
You need to create backing storage for the pointer so you have somewhere valid to write your input to.
A better idea would be to use a rock-solid input routine rather than relying on often-dodgy practices like writing to invalid memory, or allowing uncontrolled input into limited-size buffers. One such beast can be found here.

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.

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

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.

recursive strcpy function [duplicate]

This question already has answers here:
Access violation when using strcpy?
(8 answers)
Closed 9 years ago.
#include <stdio.h>
char *strcpy_r(char* s, char* t);
int main()
{
char *s = {"Bob"};
char *t = {"Billy"};
char *ptr;
ptr = strcpy_r(s, t);
printf("%s\n", ptr);
return 0;
}
char* strcpy_r(char* s, char* t)
{
if((*s = *t) != '\0')
strcpy_r(s + 1, t + 1);
return s;
}
I'm just doing this for practice, but when I compiled it. I got a seg fault from main. Could someone tell me what might've caused this seg fault?
Congratulations, you have invoked undefined behavior twice within one line.
First, you can't modify the contents of a string literal. So strcpy()ing onto "foo" is wrong.
Two, even if you could: you're copying a string to a buffer that is shorter than the string. This is UB again.
You are trying to modify a constant string. This is wrong! Chances of segfault live when you modify a constant string.
Instead do this:
char s[10] = "Bob";
char t[10] = "Billy";
char *ptr;
You can't overwrite the memory that's used to hold a quoted string. That'll segfault instantly.
String literals are constant, i.e. they cant change. You're also trying to copy a longer string into a shorter string, which will write beyond the bounds of the destination string.
Both of these problems leads to undefined behavior which can cause a crash.
To solve the first problem, you have to use an array for the destination string. To solve the other problem, you have to make sure the destination array is at least as large as the source string (including its terminating '\0').

Resources