char *reverse(char *str){
char *reverse,*temp;
int size = length(str);
temp = reverse;
/*go to last adress str*/
while(*str != '\0'){
str++;
}
/*copy str in reverse to reverse*/
do{
str--;
*reverse = *str;
reverse++;
size--;
}while(size >= 0);
return temp;
}
In this function, I get segmentation error when I assign reverse pointer to temp pointer. if i add reverse = (char*)malloc(size*sizeof(char)); it works fine. but does it have to work without adding it as a result, hasn't it already received an address.Is it because the length of the next address is about integer.
Actually reverse is just a pointer and actually there is no memory allocated where it can point to.
You can use malloc() or you can simply pass reverse as an additional argument to the function. Then you just need to be sure that it is allocated by the caller and that the size fits.
If it would be possible to point to anywhere in memory and to simply write data anywhere you want to then all programs and even the whole operating system would crash or viruses can directly infect everything... ;-)
Related
I'm trying to implement a function that concatenate two strings, but I keep getting the same error.
"pointer being realloc'd was not allocated"
When I compiled the same code on a windows machine it worked, is it something that I'm missing?
The code below is basically what I'm trying to do.
main:
int main() {
int length = 4096;
char *string = malloc(length * sizeof(char));
createString(string, length);
realloc(string, 30);
return 0;
}
createString:
void createString(char * string, int length) {
char *copyAdress = string;
char *temp ="";
int counter2 = 0;
fflush(stdin);
fgets(string, length,stdin);
while(*string != EOF && *string != *temp ) {
string++;
counter++;
}
string = copyAdress;
realloc(string, (counter)*sizeof(char));
}
Thanks!
Edit:
I want createString to change the size of string to the length of the string that I get with fgets, while having the same address as the string that I sent in, so I can allocate more memory to it later when I want to add another string to it.
There are several issues:
realloc(string, (counter)*sizeof(char)); is wrong, you need string = realloc(string, (counter)*sizeof(char)); because realloc may return a different address.
Calling createString(string, length); won't modify string
If you want a more accurate answer you need to tell us what exactly createString is supposed to do. In your code there is no attempt to concatenate two strings.
Let's work through this in order of execution.
fflush(stdin); is undefined behaviour. If you really need to clear everything in the stdin you have to find another way (a loop for example). There are compilers/systems with a defined implementation but I would not count on it.
string++; is superflous as you overwrite string after the loop.
realloc(string, (counter)*sizeof(char));
should be
char *temp = realloc(string, (counter)*sizeof(char));
if (temp != NULL)
string = temp;
This way you get the pointer where your new string is located, but I suggest you read the refecerence for realloc. In essence you do not know if it has been moved and the old address might be invalid from that point on. So dereferencing it is also undefined behaviour.
After this you would have to return the new address of string or pass the address of the pointer to your function.
The same problem repeats with the second realloc. You only got to know your first call was wrong, because the second call noticed that you do not have valid data in what you thought would be your string.
In regards to your comment: It is not possible to use realloc and to be sure that the reallocated memory is in the same place as before.
If you realloc some memory, the pointer pointing to the original memory becomes invalid (unless realloc failed and returned NULL). So calling realloc twice on the same pointer should indeed not work (if it didn't return NULL the first time).
See the answers from others about what you do wrong. However, the eror message means that on MacOS, the realloc in createString deallocated the orignal string and allocated a new one, and now your realloc in main tries to realloc a pointer that is no longer valid (allocated). On Windows, the memory was not deallocated in createString and so the second call of realloc (in main) is given a valid pointer.
I am getting error: segmentation fault core dumped.
#include<stdlib.h>
#include<stdio.h>
char *strcpy(char *s,char *t)
{
char *ptr = s;
while((*s = *t) != '\0')
s++;
t++;
return ptr;
}
int main()
{
char *s = malloc(sizeof(char) * 12);
char *t;
scanf("%s",t);
printf("%s",strcpy(s,t));
return 0;
}
You are getting segmentation fault because you are using char pointer t before allocating memory to it for getting input from user:
char *t;
scanf("%s",t); // using t before allocating memory
Allocate memory before using it:
char *t = malloc(sizeof(char) * 12);
if (NULL == t) {
fprintf (stderr, "Failed to allocate memory");
exit(EXIT_FAILURE);
}
The other problem is in function strcpy() function while loop:
while((*s = *t) != '\0')
s++;
You have not given the parenthesis in loop body so only the vary next statement is consider as loop body and every iteration of this loop will only increase the pointer s and the pointer t will keep on pointing to first character of string. At one moment of time the increment in pointer s (s++) in every iteration of while loop will make s accessing the memory beyond the allocated memory which is an undefined behavior and you may get segmentation fault. Instead you should do:
while((*s = *t) != '\0') {
s++;
t++;
}
Which is equivalent to
while(*s++ = *t++)
;
Reason is - the post increment operator increase the value of operand by 1 but [which is a pointer in this case] the value of the expression is the operand's original value prior to the increment operation. So in expression *s++ and *t++, the pointer s and t moves to the next position but returns the old content. The expression (*s++ = *t++) when assigning the null terminating character \0, the expression will result in \0 which is equivalent to 0 and the loop will terminate.
Also, make sure to free the dynamically allocated memory once you are done with it. So, after calling your string copy function you should:
free(t);
free(s);
You can also use the char array instead of dynamically allocating memory, like this:
char s[50];
char t[50];
With this you don't need to take care of allocating and freeing the memory.
Giving the function name same as the standard library function name is not a good practice. Better to give name like - mystrcpy.
Also, while copying string we only read the source string so make the source string parameter const like this:
char *mystrcpy (char *s, const char *t);
^^^^^
Avoid using single character variable names like you have used in your program - s and t. Follow good programming practice, always give name which indicate some meaning like the parameters name in your string copy function, instead of s you can give destination and instead of t you can give source.
I am trying to compare two pointers which I have basically made into strings. I have no idea how to fix this but when I run it it gives me a seg fault at the strcmp.
Here's my code:
int find_next_string(int *position, char str[], char * mem_start, int mem_size)
{
int found = 0;
char *temp2;
int k = 0;
int i=(*position+1);
char *temp ;
int temp3 = 0;
temp = (char *) calloc(mem_size, sizeof(char));
temp2 = (char *) calloc(mem_size, sizeof(char));
temp3=*position;
while(i!=temp3 && found==0 && k==0){
//for(j=0;i<mem_size;i++){
temp2=mem_start;
// j++;
temp=strstr(temp2, str);
if(strcmp(temp2, temp)==0){
found=1;
k=i;
}
//}
if(i==mem_size)
i=0;
else
i++;
}
if(found)
print_line(k, mem_start, mem_size);
// 1. update the location to the first character matching str
// 2. print the 16-byte word containing the string and repeat
// printing words until all characters in str are displayed
// 3. set found to 1
// if not found, do not change location and do not print
free(temp);
free(temp2);
return found;
}
The crash is most likely not due to the strcmp calls, but due to the fact that you reassign temp2 and then try to free the new pointer. You do the same with temp.
If those new pointers are not allocated with malloc (or calloc which is essentially malloc plus memset) then you will have undefined behavior which is a very common cause of crashes. And regarding temp it can point to the middle of some memory, and attempting to call free on that pointer (even if it point into the middle of a chunk allocated with malloc) is also UB.
The free function must be passed a pointer returned by malloc, or NULL, nothing else.
This is a basic error:
temp=strstr(temp2, str);
if(strcmp(temp2, temp)==0){
If strstr does not find the string, then temp will be NULL. Passing NULL to strcmp causes undefined behaviour, and this could be the cause of the crash.
You need to check if ( temp == NULL ) and take some action, before calling strcmp.
I want to copy one string to another string using pointer and I am getting garbage value (some unknown character) from printf function. What is wrong with it?
output is "string for copy**". At the place of ** getting some unknown character.
#include <stdio.h>
#include <conio.h>
void main()
{
char *s="string for copy",*c,*temp;//temp is used to back the
//pointer on 1st position
clrscr();
while(*s!=NULL)
{
*c=*s
c++;
s++;
}
c='\0';
c=temp;//back pointer to first position
printf("String from c:);
puts(c);
getch();
}
You need to allocate memory for your char * variables.
Also you never assign a value to temp (or allocate space for it) but then later in your code you assign c = temp. This means wherever c is currently at in memory will get assigned whatever was in memory at the location of temp.
c is char * are not allocating memory to it. So referring to it - reading from it or writing to it - is undefined behavior.
Allocate appropriate memory for c by using malloc() or other function before you copy characters into it.
So problem is not actually when you try to print using puts() but also when you copy characters to it by *c = *s.
Other than malloc(), change you code as below
...
//allocate memory for c
temp = c;
while(*s!='\0')
{
*c=*s
c++;
s++;
}
*c='\0'; //use *c
c=temp;
...
I'm trying to write a functions to modify strings in C.
If I have a function like
char *func(char *s){
char *t=s;
s++; //option 1
t++; //option 2
*t='a'; //option 2
return s;
}
If I do something like [option 1]: s++; I believe it will return the pointer to wherever s is now pointing. If I do [option 2]: t++; and *t='a'; then return s, will it return the address for the first spot of s but with modified contents or will it return the address with the original content?
char *func(char *s)
In this code, s is a pointer to a region of memory, that (I assume) represents a string.
s++;
now s points to the next char, in the same region of memory, that (I assume) represents a string.
char *t=s;
Now you have two pointers to that region of memory.
t++;
*t='a';
Now you have changed that region of memory, replacing the second character with an 'a'.
Therefore: if you then return s, you will return a pointer to that same region of memory, which was altered. If you want to return an altered copy of the string, you have to make a copy of the memory first.
char *func(char *s){
char *t=strdup(s); //duplicates a string
s++;
*t='a';
free(t); //you have to free the memory from strdup at some point
return s; //returns pointer to second character of unchanged string
}
If I do t++; and *t='a'; then return s, will it return the address for
the first spot of s but with modified contents or will it return the
address with the original content?
I believe your question assumes something like this:
char s[] = "abcde";
char *t = s;
t++;
*t = 'a';
Here you've got one string and two pointers that initially both point to the beginning of the string. At the third line, you modify one of the pointers to point to the next character. At the fourth line, you modify the data at that location. Since s points to the same data, and the data is modified, the string that s points to will change.
printf("s is: %s\n", s"); // s is: aacde
printf("t is: %s\n", t"); // t is: acde
BTW, there's no better way to really learn this stuff than to write little test programs and play with them. A good book will explain how things are supposed to work, but playing with code is the way that you grow to really understand the code and believe what the books tell you.
In the code:
char *func(char *s)
{
char *t=s;
}
you are missing a return statement, so garbage is returned.
The variable s is a local copy of whatever you passed to the function. If you write s++ inside the function, you change what the local pointer points at, but don't change the argument.
When you do t++; and *t = 'a';, you are making t point to the second character of the string passed as s, and then assigning the character 'a' to that.
So, if you have:
char *func(char *s)
{
char *t = s;
s++;
t++;
*t = 'a';
return s;
}
then the return value will be a pointer to the second character of the original string, which has been modified to contain 'a'.
What behaviour do you need?
Both returning the initial value of s, and returning the final value of s make sense.
The one option you do not have is doing *t='a' but returning with the original memory unchanged. Memory is changed
Returning the original s is quite common, for example strcpy.
It is also common to return a pointer to 'the next char after the one I just modified' (which is an option you did not offer).
You need to think through, and decide what is the helpful thing for the function to do?