My code is compiled fine but the second printf of my code is not printing.
#include<stdio.h>
int main()
{
char * const p="pointerconstant";
printf("%s",p);
*p='B';
printf("\n%s",p);
}
When I run the following program, it outputs..
pointerconstant
pointerconstant
But it should be..
pointerconstant
Bointerconstant
What is the problem here?
i think your issue is similar: https://stackoverflow.com/a/7547849/5809736
From #bdonlan for your code:
Note that if you did this, it would work:
char p[] = "pointerconstant";
printf("first=%s",p);
*p='B';
printf("\nsecond=%s",p);
This is because we're initializing a non-const character array. Although the syntax looks similar, it is treated differently by the compiler.
In this line
*p='B';
You're trying to modify the first byte of the char array that the pointer points to. This doesn't work because that's a read-only part of your program's binary. Fix it by copying it to the stack or heap:
#include<stdio.h>
#include<string.h>
int main()
{
char * const p = strdup("pointerconstant"); // string is copied to the heap
printf("first=%s", p);
*p = 'B';
printf("\nsecond=%s", p);
free(p); // copy of the string on the heap is released again
return 0; // 0 indicates that the program executed without errors
}
The result is:
first=pointerconstant
second=Bointerconstant
On a side note, in my opinion it would be more idiomatic to write *p = 'B'; as p[0] = 'B';, but that's up to you, of course.
Note: this answer is in C, the question is also tagged as C++
Related
I am presently new to programming and am following the C language which is being taught to us in our College.
I have doubt in the actual functioning of the strcpy() function under the header-file #include<strings.h>
The general use of this function is given below -
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char a[] = "google";
char *b = (char*)malloc((strlen(a) +1)*sizeof(char));
strcpy(b,a);
printf("%s, %s\n", a, b); //prints google, google
free(b);
}
We are given the following format and prototype of the same :
char *strcpy( char *to, const char *from)
{
char *temp = to;
while (*to++ = *from++);
return temp;
}
I have a couple of doubts about this-
What is an extra pointer ( temp ) requirement in the function? Can't we just return to; at the end of the function?
I convinced myself that the temp variable is used because during each while loop, the pointer to is changing itself. That is first *to will be assigned *from and then to = to +1, and from = from +1, will take place which will result in changing the address stored in the pointer to. But if this is true, then what about the pointer from? Will, it also not change at the end of the strcpy() function?
Where is the function returning the address stored in temp? ( the function should only work if b = strcpy(b,a); be mentioned not only strcpy(b,a);)
To check the given function I also made my own function "strcpy_me" and used it with the same format and prototype, and it gave the same results.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char *strcpy_me( char *to, const char *from)
{
char *temp = to;
while (*to++ = *from++);
return temp;
}
int main()
{
char a[] = "google";
char *b = (char*)malloc((strlen(a) +1)*sizeof(char));
strcpy_me(b,a);
printf("%s, %s\n", a, b); // prints google, google
free(b);
}
Please help me clarify my doubt.
see 2
It's a requirement from the implementation of strcpy to return a pointer to the beginning of the destination string. So if you want to implement your function in the same way as strcpy, you'll have to save a copy of the original pointer passed as parameter, in case you intend to change that parameter inside the function. This isn't a particularly useful or rational feature, but strcpy has been like that since the dawn of time.
Not sure what you mean; here obviously: return temp;
return to; is wrong. You have to realize that the function returns a value whether that value is used by the caller or not. Strict compilers might warn "value from function isn't used" in which case you'd have to write (void) strcpy(a,b); to silence it. Since your example doesn't use the returned value, it doesn't matter that it is wrong.
What you think in no. 2 is correct.
from does get changed but we don't need the previous value of from. to was stored in temp as to's original value should be returned, so we need it but no need for from.
No, you don't need to do that. You can ignore return values in C(in most cases without warnings as well). No returning works as doing *to = *from changes the parameter's memory as well, in this case, b. So, *to = *from changes the array b directly. It is because to and b store the same memory.
Note: In your while loop, it's *to++ = *from++. It uses post addition, which for simplification, I didn't include here but all it does is increment both to and from after the operation.
As I said in 3, you don't need the return value. In fact, because original to and temp point to the same memory as b, the function returns b itself. doing, b = strcpy_me(b, a) is the same as:
strcpy(b, a);
b = b; //b's value stays the same
And yes, return temp; is absolutely garbage in my opinion. It only causes confusion.
I'm trying to learn about pointers in the C language. But I have a question regarding dereferencing them.
This piece of code works fine, it displays 'i' as I desire.
Code-1
#include <stdio.h>
void myfunction(char** str);
int main()
{
char *name = "Gianni";
myfuntion(&name);
return 0;
}
void myfunction(char** str){
char* test = *str;
printf("%c", test[1]);
}
But what I guessed to have the same result turns out to be a little bit different. My question is why do I not get the same result from the second piece of code?
I dereferenced the pointer so it points to the first character again and can read it until the '\0' terminator. So I thought it would be possible to display the single characters here as well.
Code-2
#include <stdio.h>
void myfunction(char** str);
int main()
{
char *name = "Gianni";
myfuntion(&name);
return 0;
}
void myfunction(char** str){
printf("%c", *str[1]);
}
This is precedence issue.(Array subscript [] has higher precedence than dereference *). You should try
(*str)[1]
This will give you the correct result. In earlier case (In Code-2) you had undefined behavior. You were de-referencing str[1] which is pointing to out of bound memory.
So initially what you were doing in Code-2
*str[1] --> *(*(str+1))
Now what we did,
(*str)[1] --> *((*str)+1)
Well in the modification you are basically getting the address of the array (string literals are array which decayed into pointer) and then you index into correct position - which will give you the correct result.
Well if you check earlier example you will see the similarity. Earlier code (Code-1) you print temp[1] which is *(temp+1) But what is temp? In the line before you did this temp = *str so what is it you are doing?
*(temp+1) --> *(*str+1) --> *((*str)+1)
It is a code written to copy one pointer to another.
ERROR is Segmentation error (core Dumped)
#include<stdio.h>
char strcp(char *,char *);
int main()
{
char *p="string",*q;
printf("%s",p);
strcp(p,q);
printf("%s",q);
return 0;
}
char strcp(char *p,char *q)
{
int i;
for(i=0;*(p+i)!='\0';i++)
*(p+i)=*(q+i);
}
char *p="string"...
strcp(p,q);
What p points to is a literal and literals are read-only. Trying to copy anything to it is forbidden (and causes a segmentation fault).
...and q is not initialized, another possible cause of the seg fault.
The problem with this algorithm is an implicit assumption it makes about pointers: char *q is not a string, it is a pointer to character. It can be treated as a string if you allocate space and place a null-terminated sequence of characters into it, but your code does not do it.
You can allocate space to q with malloc, like this:
char *p="string";
char *q=malloc(strlen(p)+1);
In addition, your version of strcpy reads null terminator from a wrong pointer, and does not null-terminate the copied string:
char strcp(char *p, char *q)
{
int i;
for(i=0;*(q+i)!='\0';i++) // <<== Fix this
*(p+i)=*(q+i);
*(p+i) = '\0'; // <<== Add this line
}
As the other answers have indicated the problem starts* with char *p="string",*q;.
The Literal "string" compiles to the equivalent:
const char foo[7] = {'s','t','r','i','n','g','\0'}; why *\0
As you might see further in you code you're trying to copy data to a const a\rray. Which is illegal.
But you're playing C, you have implicitly casted the const char foo[] to a char *p, right there during initialization.
C is not type safe because it's tightly coupled to the actual instruction on the hardware. Where types don't exist anymore, just widths. But that is for another topic.
*It's not the only flaw. I tossed in a few explanatory wiki links. Because the question shows you're a novice programmer. Keep up the work.
I'm watching a course online learning C and I stumbled upon something that is crashing my program.
In the video they show the following code snippet :
#include <stdio.h>
int main()
{
char* ch;
int num = 12345;
sprintf(ch, "%d", num);
printf("%s\n", ch);
return(0);
}
I've decided to make my own little program and test it.
Here's the code I've written :
#include <stdio.h>
#define A 65
int main()
{
int n = A;
printf("n is equal to %d\n", n);
n = atoi("10");
printf("n is equal to %d\n", n);
char* ch;
sprintf(ch, "%d", n);
printf("ch is equal to %s\n", ch);
return 0;
}
When I run my program, the output is as follow :
n is equal to 65
n is equal to 10
After this part my program crashes.
I assume the sprintf function is causing this but I'm not sure why, I'm new to the language so I wouldn't know, I think I've done everything correctly judging by the code snippets that was shown in the video.
Could someone please explain me what I did wrong ?
Thanks in advance.
In the video they show the following code snippet: [...]
If this is a snippet that they say should work, stop watching that video: the snippet has undefined behavior, there is no chance that it would work properly unless by an unlucky coincidence.
I've decided to make my own little program and test it.
Your program has the same exact problem: the buffer to which sprintf is writing has not been initialized. Change the declaration of ch to allocate some space to it, like this:
char ch[20];
This will prevent your code from writing to memory pointed to by an uninitialized pointer, fixing the undefined behavior.
Could you explain to me how char* could be used?
If you would like to use char*, assign it a result of malloc of a proper size, and free the result at the end:
char *ch = malloc(20);
... // Put the rest of the code here
// Add this line before the end:
free(ch);
You need to alocate memory for ch or else use an array instead of a pointer.
char* ch = malloc(sizeyouwant * sizeof(char));
Where sizeyouwant is the number of characters you will store.
The problem is here:
char* ch;
this is just a char pointer, it needs to point to allocated memory to hold the string:
char ch[32];
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.