Copying the string of pointer to other pointer - c

Folks,
I have basic and simple question on pointers. The below is code is giving a segmentation fault.
int main()
{
char *str = "hello, world\n";
char *strc = "good morning\n";
strcpy(strc, str);
printf("%s\n", strc);
return 0;
}
Can't we copy from pointer to other.
if i have char *strc = "good morning\n", can't i do like this
strc[5] = '.';. Why this also giving a seg fault.

You may not change string literals. It is what you are trying to do in statement
strcpy(strc, str);
that is you are trying to overwrite string literal "good morning\n" pointed to by pointer strc.
Of cource you may use pointers in function strcpy. The valid code can look like
#include <stdio.h>
#include <string.h>
int main()
{
char *str = "hello, world\n";
char strc[] = "good morning\n";
strcpy(strc, str);
printf("%s\n", strc);
return 0;
}
Or
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char *str = "hello, world\n";
char *strc = malloc( 14 * sizeof( char ) );
strcpy( strc, "good morning\n" );
//...
strcpy(strc, str);
printf("%s\n", strc);
free( strc );
return 0;
}

Related

Change pointer of pointer in C

I'm trying to write a void function that gets a pointer to a pointer of a string (char**) as a parameter, and changes the original char* so it pointed to another string, lets say "hello".
Below is the code I've written:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void change_ptr(char **str_ptr)
{
char hello[] = "hello";
char *hello_ptr = hello;
*str_ptr = hello_ptr;
}
int main()
{
char str[] = "yay";
char *str_ptr = str;
char **ptr_to_str_ptr = &str_ptr;
change_ptr(ptr_to_str_ptr);
printf("%s\n", str);
return 0;
}
As you can see, Im getting the pointer to the pointer of the char* "yay", delivering it to the function, and in the function I'm getting the pointer to "hello", and changes *str_ptr (which is the pointer to the original string) to the pointer to hello. But when I print str at the end, it prints "yay".
What am I doing wrong?
(when I debug with printing the addresses, everything seems fine.)
This works:
#include <stdio.h>
void change_ptr(const char ** str_ptr)
{
*str_ptr = "hello";
}
int main()
{
char str[] = "yay";
const char * str_ptr = str;
const char ** ptr_to_str_ptr = &str_ptr;
change_ptr(ptr_to_str_ptr);
printf("%s\n", str_ptr);
}
Note that the string "hello" in this example is read-only because it is a string literal. I added const in a few places so you are reminded of this and the compiler will warn you if you try to write to the string. The pointer str_ptr can be modified, but not the string itself.

Strcpy thru array subscribed

In the Ritchie/Kernighan book, they show a few ways how to create a self made strcpy function, one of them is with using array subscribed instead of char pointers , but when I try this method and run the code it only gives me the second word in this case "world" and not the word "hello"
any clue?
#include <stdio.h>
void xstrcpy(char *a, char *b)
{
int i = 0;
while((a[i] = b[i]) != '\0')
{
i++;
}
}
int main()
{
char name[20] = "hello";
char names[20] = "world";
xstrcpy(names, name);
printf("%s\n", names);
}
Your function overwrites a with the content of b. You could call as like this:
xstrcpy(names + strlen(names), name);
Or you could implement concatenation. Require caller to pass in a sufficiently large string array (dest). Then find the end (end) of the string and copy src to dest. Using the pointers passed in, but you could also use separate indices into dest and src:
#include <stdio.h>
#include <string.h>
// require caller to pass in a dest array large enough for a copy of src
char *xstrcat(char *dest, const char *src) {
char *end = strchr(dest, '\0');
while(*end++ = *src++);
return dest;
}
int main() {
char dest[sizeof("hello") + sizeof("world") - 1] = "hello";
char src[] = "world";
xstrcat(dest, src);
printf("%s\n", dest);
return 0;
}

"initializer element is not constant char" error in C

Here is my code:
#include <stdio.h>
#include<stdlib.h>
char *s = (char *)malloc (40);
int main(void)
{
s="this is a string";
printf("%s",s);
}
I am getting the following error:
error: initializer element is not constant char *s = (char *)malloc
(40);
You don't need to allocate memory in this way if you wanna initialize it in code, I mean:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *s = "this is a string"; // char s[] = "this is a string";
printf("%s",s);
return 0;
}
is just enough in this case. If you really want to assign const char string to your char array, this topic should enlighten you: Dynamically allocating memory for const char string using malloc()
You cannot not do that.
You can do this instead -
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
char *s; // probably should avoid using global variables
int main(void)
{
s=malloc(40);
strcpy(s,"this is a string");
printf("%s",s);
free(s);
}
Other than this inside main you can do this -
char *s="this is a string"; //string literal you can't modify it
Or
char s[]="this is a string"; // modifiable string
You assign a pointer to a string constant to a variable, s, which is not declared to point to a constant. This is what you want:
#include <stdio.h>
int main(void)
{
const char *s = "this is a string";
printf("%s\n", s);
return 0;
}
In C there are basically three ways to declare "string" variables.
String constant pointers
If you need a name for a string that will not change, you can declare and initialize it like
const char *s = "a string";
Character arrays
If you need a string variable and you know in advance how long it needs to be you can declare and initialize it like
char s[] = "a string";
or like
char s[9];
strcpy(s, "a string");
Character sequence pointers
If you don't know in advance how large the array needs to be, you can allocate space during program execution:
char *s;
s = malloc(strlen(someString) + 1);
if (s != NULL) {
strcpy(s, someString);
}
The "+1" is to make room for the null character (\0).

strcpy function: C

I am trying to implement
void strcpyy(char *s, char *t){
while(*s++ = *t++){
}
}
which is an example from K&R. The implementation should be fairly easy but for some reason, that is not the case for me at the moment. So I have the following
int main(){
char *mess = "hello world";
char *mess = (char *) malloc(strlen(mess) + 1);
char *aess;
strcpyy(aess, mess);
printf("%s", aess);
return 0;
}
Every time I run the program, I keep on getting a big list of errors each time I run with -Wall. I would think that to implement and use strcpyy, you would have to malloc space to copy the string and once you do so, you should be able to print out aess which theoratically should contain a copy of mess. Any help would be much appreciated!
It is always a good practice to pay attention to the error messages, especially to the first message (others often are the consequences of the first error). The error message surely indicated the line number corresponding to the line with malloc, and most probably told you what's the problem there.
Correct your program to read:
char *mess = "hello world";
char *aess = (char *) malloc(strlen(mess) + 1);
or the complete function is:
int main(){
char *mess = "hello world";
char *aess = (char *) malloc(strlen(mess) + 1);
strcpyy(aess, mess);
printf("%s", aess);
return 0;
}
The problem is that your line
char *mess = (char *) malloc(strlen(mess) + 1);
overwrites the first line
char *mess = "hello world";
and the line
char *aess;
leaves the variable unassigned.
The compile error is because the compiler cannot choose between
char *mess = "hello world";
and
char *mess = (char *) malloc(strlen(mess) + 1);
which introduce a new variable each but with the same name.
The program will look the following way
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void strcpyy( char *s, const char *t )
{
while ( *s++ = *t++ );
}
int main( void )
{
char *t = "hello world";
char *s = ( char * )malloc( strlen( t ) + 1 );
strcpyy( s, t );
printf( "%s\n", s );
free( s );
return 0;
}
change
char *mess = "hello world";
char *mess = (char *) malloc(strlen(mess) + 1);
char *aess;
to
char *mess = "hello world";
char *aess = malloc(strlen(mess) + 1);
mess is a string literal, which is hold in read-only memory. you were overwriting it and losing string that you wanted to copy. you need to assign some space for place where you want to copy characters, in your case aess variable. also, remember to free(aess); at the end of your program. if not, you'll get memory leaks.
why are you declaring and defining mess two times? never declare two variables with the same name if they have the same scope ,by doing this you confuse the compiler;
I'd recommed using strdup like this :
int main(){
char *mess = strdup("hello world");
char *aess;
strcpyy(aess, mess);
printf("%s", aess);
return 0;
}
or just a plain array like this
int main(){
char mess[] = "hello world";
char *aess;
strcpyy(aess, mess);
printf("%s", aess);
return 0;
}

Why is this usage of memset() segfaulting?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char *str = "This is a string!";
int therealthing = sizeof(str[0]) * 4;
memset(str, 'b', therealthing);
printf("%s\n", str);
return 0;
}
This code causes a segfault, any ideas why?
I have already tried passing it as a memory address and as a pointer.
This is a string literal. It's immutable. Can't be changed.
char *str = "This is a string!";
You're trying to change it with memset. You could use an array of characters
char str[] = "This is a string!";
or
char * str = malloc(sizeof(char) * (strlen("This is a string!") + 1));
strcpy(str, "This is a string!");
You can't modify a string literal. It will invoke undefined behavior.
Try this instead
char str[] = "This is a string!";

Resources