memcpy error : Segmentation fault (core dumped) - c

I'm trying to copy one string to another in c using memcpy with the following code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct fullName
{
char* firstName;
char* lastName;
} NAME;
int main()
{
NAME myName, hisName;
myName.firstName = "aaaaaaa";
hisName.firstName = "bbbbbb";
memcpy(myName.firstName, hisName.firstName, sizeof(hisName.firstName));
printf("myName.firstName = %s\n", myName.firstName);
printf("hisName.firstName = %s\n", hisName.firstName);
}
and it gives Segmentation fault (core dumped) Error after running the program
I tried to declare firstName and lastName as pointer to an array of chars rather than pointer to char but the error persists . what am I missing ?! plz help...
FYI .. I'm working on Ubuntu 14 and I'm using gcc (Ubuntu 4.8.2-19ubuntu1)...

In these statements
myName.firstName = "aaaaaaa";
hisName.firstName = "bbbbbb";
you initialized pointers with addresses of string literals.
In next statement
memcpy(myName.firstName, hisName.firstName, sizeof(hisName.firstName));
you try to modify one of the string literals.
According to the C Standard (6.4.5 String literals)
7 It is unspecified whether these arrays are distinct provided their
elements have the appropriate values. If the program attempts to
modify such an array, the behavior is undefined.
Also this expression
sizeof(hisName.firstName)
returns size of the pointer itself. It is not the same as the size of the corresponding string literal.
The valid program could look the following way
#include <stdio.h>
#include <string.h>
typedef struct fullName
{
char firstName[8];
char lastName[8];
} NAME;
int main()
{
NAME myName = { "aaaaaaa" };
NAME hisName = { "bbbbbb" };
memcpy( myName.firstName, hisName.firstName, sizeof( hisName.firstName ) );
printf( "myName.firstName = %s\n", myName.firstName );
printf( "hisName.firstName = %s\n", hisName.firstName );
}

You are assigning myName.firstName and hisName.firstName with pointers to string literals. String literals cannot be modified, which is what's causing your error.
To achieve what you want, you can either declare firstName as a char array, or allocate memory to it (as a char pointer).
Array method:
typedef struct fullName
{
char firstName[256]; // a sufficiently large number
char lastName[256];
} NAME;
int main()
{
NAME myName, hisName;
strcpy(myName.firstName, "aaaaaaa"); // You can't assign a string directly
strcpy(hisName.firstName, "bbbbbb");
memcpy(myName.firstName, hisName.firstName, sizeof(hisName.firstName));
printf("myName.firstName = %s\n", myName.firstName);
printf("hisName.firstName = %s\n", hisName.firstName);
}
Allocation method:
typedef struct fullName
{
char* firstName;
char* lastName;
} NAME;
int main()
{
NAME myName, hisName;
size_t buffersize = 256; // a sufficiently large number
myName.firstName = malloc(buffersize);
hisName.firstName = malloc(buffersize); // same for lastName
strcpy(myName.firstName, "aaaaaaa");
strcpy(hisName.firstName, "bbbbbb");
memcpy(myName.firstName, hisName.firstName, buffersize); // You can't use sizeof() as this will give the size of a pointer
printf("myName.firstName = %s\n", myName.firstName);
printf("hisName.firstName = %s\n", hisName.firstName);
}

This did not crash in MSVC, it produced the output:
myName.firstName = bbbbaaa
hisName.firstName = bbbbbb
Notice that only 4 chars from hisName have been copied to myName. That is because
sizeof(hisName.firstName)
is 4 on your platform, the size of the pointer. But manipulating such strings is Undefined Behaviour anyway.

Related

Why is there a segmentation fault in strcpy after initializing a struct?

I can't seem to figure out why strcpy makes a segmentation fault in this code. It should be straightforward:
typedef struct message {
char *buffer;
int length;
} message_t;
int main () {
char* buf = "The use of COBOL cripples the mind; its "
"teaching should, therefore, be regarded as a criminal "
"offense. -- Edsgar Dijkstra";
message_t messageA = {"", 130};
message_t *message = &messageA;
strcpy(message->buffer, "buf");
printf("Hello\n");
}
EDIT: strcpy(message->buffer, "buf") is supposed to be strcpy(message->buffer, buf) without the "" quotes
EDIT: Thank you to the comments! This has been resolved by malloc'ing message->buffer to make space for buf:
message_t messageA = {"", 130};
message_t *message = &messageA;
message->buffer = malloc(122);
strcpy(message->buffer, buf);
printf("Hello\n");
some points to be noted here.
when you declare pointers to store data you either assign directly at the declaration (usually used for small strings not big strings) or you should allocate memory using
dynamic memory allocation functions
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct message {
char *buffer;
int length;
} message_t;
int main () {
char* buf = "The use of COBOL cripples the mind; its "
"teaching should, therefore, be regarded as a criminal "
"offense. -- Edsgar Dijkstra";
message_t messageA = {"", 130};
message_t *message = &messageA;
//allocate memory to buffer length of buf, + 1 for \0 character
message->buffer = malloc( strlen(buf) + 1 );
// check allocated memory is success or not
if ( message->buffer )
{
strcpy(message->buffer, buf);
printf("buffer = %s\n",message->buffer );
//free the malloc'ed memory to avoid memory leaks
free(message->buffer);
//make the pointer NULL, to avoid dangling pointer
message->buffer = NULL;
}
else
{
printf("malloc failed\n");
}
printf("Hello\n");
return 0;
}
message_t messageA = {"", 130};
Here, you initializing messageA.buffer = "". It is a string literal. So, you cannot modify the string stored in it. If you try to modify it, you will get segmentation fault.
message_t *message = &messageA;
strcpy(message->buffer, buf);
Here, you are modifying the string literal message->buffer. That's why you got segmentation fault.
Please visit this question Modifying a string literal
Try using message->buffer = strdup(buf); that does the malloc and strlen computation for you.

Function not modyfing a character array

Im just starting to learn pointers and I'm trying to figure out why my code doesn't work. I get no compilation error yet the code doesn't what I want it to do. Why am I not passing the adress of an array? If I try to do so I get a compiilation error :(
#include <stdio.h>
void switch_name(char* name)
{
name= "testv2";
}
void main()
{
char *name1 = "test_name";
printf("%s\n", name1);
switch_name(name1);
printf("%s\n", name1);
}
Well because C is pass by value. You make changes to a local variable(name in function swicth_name()). To retain changes pass the address of the char* and assign the address of the string literal to the char* directly (By dereferencing the char**). For example this would work
#include <stdio.h>
void switch_name(char** name)
{
*name= "testv2";
}
int main(void)
{
char *name1 = "test_name";
printf("%s\n", name1);
switch_name(&name1);
printf("%s\n", name1);
return 0;
}
Here the function swicth_name got the address of the char* name1. Now when you dereference it using unary * in switch_name you assign the address of the string literal to the name variable of main(). That' swhy the change retains.
Function parameters are its local variables.
You can imagine the function call and its definition the following way
char *name1 = "test_name";
switch_name(name1);
//...
void switch_name( /* char* name */ )
{
char *name = name1;
name= "testv2";
}
As you can see the original variable name1 was not changed in the function. It is the variable name that is the parameter that was changed in the function.
You have to pass the original variable by reference if you are going to change it in the function.
For example
#include <stdio.h>
void switch_name( char ** name)
{
*name= "testv2";
}
int main( void )
{
char *name1 = "test_name";
printf("%s\n", name1);
switch_name( &name1 );
printf("%s\n", name1);
}
Compare the above program with the following program
#include <stdio.h>
#include <string.h>
void switch_name( char* name )
{
strcpy( name, "testv2" );
}
int main(void)
{
char s[] = "test_name";
char *name1 = s;
printf( "%s\n", name1 );
switch_name( name1 );
printf( "%s\n", name1 );
return 0;
}
In the first program you are going to reassign the original pointer itself using a function.
In the second program it is the data pointed to by the pointer that are reassigned using the standard C function strcpy.
Take into account that according to the C Standard the function main without parameters shall be declared like
int main( void )

Return the address of a global string variable

How do I return the address of a global char* variable? I have to do this for a project. I have to write the function based on pseudo code which looks like this:
string* get_variable_address();
C doesn't have string so I assume string* will become char**. I've tried many things but I can't get it to work. What I have looks something like this:
#include <stdio.h>
char test[100] = "Get my address";
int main(void) {
char** address = return_variable_address();
printf("The address is: %s\n", *address);
return 0;
}
char** return_variable_address() {
return &test;
}
C doesn't have string so I assume string* will become char**
Probably not. A string in a C is a character array, which you can access through a char*. Therefore you can simplify your program quite a bit to get the desired result:
#include <stdio.h>
char* return_variable_address (void);
char test[100] = "Get my address";
int main(void) {
char* address = return_variable_address();
printf("The content stored at the address: %s\n", address);
return 0;
}
char* return_variable_address (void) {
return test;
}
Please note that all of this is bad practice - avoid global variables.
Keeping your following requirements in mind -
You want to return a char** where one deferencing once gives you the string "Get my address"
You want the string to be mutable.
So you can do
char test[100] = "Get my address";
char *pointer = test;
char** return_variable_address(void) {
return &pointer;
}
int main(void) {
char** address = return_variable_address();
printf("The address is: %s\n", *address);
(*address)[0] = 'F'; //Test for mutability
printf("The address is: %s\n", *address);
return 0;
}
I understand that these requirements are for some security testing and hence are so peculiar.
Demo here: Ideone
It might help you to typedef a definition of string. Then it is easy to see that the address of a string variable s is just &s as for any other address. I expect that string is used a lot through the project and the typedef will also save you from trying to change every string to char*.
To print an address use the format flag %p.
#include <stdio.h>
typedef char string[10]; // string defined as an arrary of 10 chars
string s = "Hello world"; // I've deliberately put a common error in here
string* return_variable_address( void )
{
return &s;
}
int main( void )
{
printf("Address of global var s = %p \n", return_variable_address() );
return 0;
}

How can I add a string variable in the middle of another string?

I have a c program as below:
char* data1 = "test";//Here i have given some dummy value, the value will be evaluated in runtime
char* variable1 = "<Method name=\"data1\">";
The problem i am facing with this code is, instead of data1's value data1 variable name it self is getting stored for variable1. So i want to know here in the place of variable data1 (as available in line 2), how can i get test which is its value during execution.
Expected result for variable1: <Method name="test">
Actual result i expect for variable1: <Method name="data1">
In java i use a "+" operator, i am struggling for the implementation in C.
You can use sprintf or snprintf functions and %s placeholder, as following:
#include <stdio.h>
int main (void)
{
char* data1 = "test";//Here i have given some dummy value, the value will be evaluated in runtime
char* variable1 = "<Method name=\"%s\">";
char result[500];
sprintf(result, variable1, data1);
snprintf(result, 500, variable1, data1);
return 0;
}
If you are talking about variable declaration you can use string concatenation macro.
#include <stdio.h>
#define STRCAT(a, b, c) a b c
#define STR1 "test"
char* data1 = STR1;
char* variable1 = STRCAT("<Method name=\"", STR1, "\">" );
int main(void)
{
printf("%s\n", variable1);
}
If you waht to build it runtime you can use, as already suggested snprintf:
#include <stdio.h>
#include <string.h>
int main(void)
{
char* data1 = "test";
char* variable1 = "<Method name=\"%s\">";
char output[strlen(data1)+strlen(variable1)-1];
snprintf(output, sizeof(output), variable1, data1 );
printf("%s\n", output);
}
As you can see the resulting size of output array is calculated as:
strlen(data1) = 4
strlen(variable1) = 18
We have to remove 2 chars from variable1 length due to format "%s" and add 1 byte for null terminator because of strlen computes the length of a C-string but not including the terminating null character.
As pointer out by #alk VLA could not be supported by your compiler, So, Last example can be using malloc
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char* data1 = "test";
char* variable1 = "<Method name=\"%s\">";
size_t output_size = strlen(data1)+strlen(variable1)-1;
char *output = malloc(output_size);
if (output != NULL)
{
snprintf(output, output_size, variable1, data1 );
printf("%s\n", output);
}
else
{
fprintf(stderr, "malloc error");
}
free(output);
}
As you can see a memory is allocated dynamically and you must check that the required amount of byte were allocated successfully (pointer != NULL) and free the memory before exit. Because of c has not garbage collector, as java have.

Segmentation Fault - String Concatenation in C Error

I am fairly new to C programming and still trying to understand all the nooks and crannies of C. I am writing a program to concatenate two strings. But I am getting an error which I don't understand. Here is the output.
Asfakul
The Length of the String name is 7
The Length of the String fullname is 7
L
Segmentation fault (core dumped)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char const *argv[])
{
char *name="Asfakul";
char *surname="Laskar";
char *fullname;
int i=0;
//Allocate Memory of 100 char
fullname=(char*)malloc(100*sizeof(char));
fullname=name;
while(*name !='\0')
{
i++;
name++;
}
// Allocate Memory for FullName
//fullname=(char*)malloc(100*sizeof(char));
//Coppied the spurce String
// fullname=name; // Here this assignement will not work as Pointer name now point to NULL character of String Name.
puts(fullname);
printf("The Length of the String name is %d\n",i );
printf("The Length of the String fullname is %d\n",strlen(fullname) );
while(*surname !='\0')
{
printf("%c\n",*(fullname+i+1));
*(fullname+i+2)=*(surname);
printf("%c\n",*(surname));
i++;
surname++;
}
puts(fullname);
return 0;
}
Please help me understand what I am doing wrong.
fullname = name; assigns the pointer name to fullname. You subsequently modify the data at name. That's not allowed since name points to a read-only string literal.
You're also discarding the malloc pointer, leaving you no way to free the allocated memory! This will not end well.
You should take a deep copy of name instead: consider using a strncpy.
If you were to use const char* for the string literals then compilation should fail, so protecting yourself from these kind of things.
*(fullname+i+2)=*(surname);
Here you are trying to cat the surname at the end of the name:
char *name="Asfakul";
This is read-only space.
You should alloc enough space for both strings and copy them inside the allocated space.
You can past char by char
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char const *argv[])
{
char *name="Asfakul";
char *surname="Laskar";
char *fullname;
int i=0;
//Allocate Memory of 100 char
fullname=malloc(100*sizeof(char));
while(*name !='\0')
{
fullname[i++] = *name++;
}
fullname[i] = '\0';
puts(fullname);
printf("The Length of the String name is %d\n",i );
printf("The Length of the String fullname is %zd\n",strlen(fullname) );
fullname[i++] = ' ';
while(*surname !='\0')
{
fullname[i++]= *surname++;
}
fullname[i] = '\0';
puts(fullname);
free(fullname);
return 0;
}

Resources