I am trying to copy a string into another char pointer variable using strcpy function.But I always get segmentation fault.Here is my code.
/* strcat example */
#include <stdio.h>
#include <string.h>
int main()
{
char str[100]="";
char *pch3;
strcpy(pch3,"Ravi");
//strcat(str,pch3); //Segmnetation fault.
puts(pch3);
return 0;
}
If I do the same thing in this one I still get segmentation fault.
else
{
misc_rec_cnt++;
fp1=fopen("breast-cancer-wisconsin-miscellaneous.data","a");
fprintf(fp1,"%s",line2);
fclose(fp1);
fp2=fopen("missingSCNs.data","a");
pch2=strtok(line2,",");
fprintf(fp2,"%s\n",pch2);
fclose(fp2);
//pch3=(char *)malloc(sizeof(char)*strlen(line3));
pch3 = strtok(line3,",");
while(pch3!=NULL)
{
if(strcmp(pch3,"?") == 0)
{
strcat(str1,"0");
strcat(str1,",");
}
else
{
//strcat(str1,pch3);
strcat(str1,",");
}
pch3 = strtok(NULL,",");
}
strlen1=strlen(str1);
memcpy(str2,str1,strlen1-1);
fp3=fopen("breast-cancer-wisconsin-miscellaneous-cleansed.data","a");
fprintf(fp3,"%s\n",str2);
fclose(fp3);
}
You need to allocate the space for pch3 before you copy to it. Use malloc to create a char array large enough to accomodate the elements of your source string before you copy it. What you are currently doing is declaring a char pointer and not initialising it. Therefore the memory location that it points to could be anywhere - and that means that you should probably not be attempting to write to it - which is why you are getting the segfault. Using malloc will allow you to allocate a region of memory that you are safe to write to and this will solve your problem (assuming the call to malloc succeeds). You cannot just go writing data to random memory locations without getting segfaults and access violations.
pch3 is a char pointer, but it doesn't have any storage associated with it which is the cause of the problem. Call malloc() to allocate some memory that the pch3 pointer can point to and you should be ok.
At this point you have a char pointer that is uninitialized and just pointing somewhere unknown. So try this:
pch3 = (char *)malloc(sizeof(char) * 100); /* 100 just as an example */
This tutorial might be helpful or this SO question: Allocating char array using malloc
pch3 is an unallocated pointer, so you're writing data to a location that doesn't exist. Did you mean to assign it to str?
char str[100]="";
char *pch3;
pch3 = str;
strcpy(pch3,"Ravi");
I'd recommend that you first allocate memory before copying data to a random place.
strcpy(pch3=(char*)malloc(sizeof("Ravi")),"Ravi");
but better check if it didn't return null pointer.
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.
Having some issues comparing char arrays thru pointers. I am working without both the string library and iostream, would like to keep it that way.
char *GetCurrentPath()
{
char buffer[MAX_PATH];
if (!GetModuleFileNameA(NULL, buffer, MAX_PATH)) {
printf("GetModuleFileNameA failed, error: %d\n", GetLastError());
}
return (buffer);
}
char *GetInstallPath()
{
char buffer[MAX_PATH];
if (!SHGetSpecialFolderPathA(NULL, buffer, CSIDL_APPDATA, FALSE)) {
printf("SHGetSpecialFolderPathA failed, error: %d\n", GetLastError());
}
strcat(buffer, "\\service.exe");
return (buffer);
}
char *InstallPath = GetInstallPath();
char *CurrentPath = GetCurrentPath();
if (InstallPath == CurrentPath)......
The if statement causes an instant crash, same goes for strcomp.
Suggestions?
What you are currently doing is undefined behavior. The buffers that you are using in the two functions are defined locally to those functions and go out of scope the moment the functions end, giving you pointers to random stack addresses.
You need to either allocate the buffers in the functions:
Replace : char buffer[MAX_PATH];
With: char *buffer = new char[MAX_PATH]
Or pass allocated buffers from your main to the functions:
char *InstallPath = new char[MAX_PATH];
GetInstallPath(InstallPath);
And change your get path functions:
char *GetInstallPath(char *buffer)
In both cases, you will have to delete your pointers before ending your program to free up the memory.
On top of that, when you try to compare the two variables, they will compare pointer addresses rather than string contents. You will need to use strcmp() or something in that family of functions.
Your functions return an array (char *) declared locally inside them. Your pointers have undefined values outside the functions. You can't do that.
You may allocate them dynamically:
char *buffer = malloc(MAX_PATH*sizeof(char));
Since both buffers are allocated on stack, they are freed after the function execution ends. So, the pointers function returns becomes invalid.
To fix that, you have to allocate buffer[] on heap, using char * buffer = new char[MAX_PATH];
But after you will have to free the memory manually.
I used this code to print some string,but it does not print any thing.What is the problem?
char* getNotFilledEncryptionParams(void)
{
char* nofilledStr;
char tmp[3];
const char * arr[]= {" P,"," Q,"," A,"," B,"," C,"," R,"," S0,","S1,","S2,","F1,","G1"};
for(i=0;i<11;i++)
{
if(filledParams[i] == 0)
{
strcpy(tmp,arr[i]);
strcat(nofilledStr,tmp);
}
}
return nofilledStr;
}
Usage:
int main(void){
char *remaining;
remaining = getNotFilledEncryptionParams();
printf("\r\n Remaining item:%s",remaining);
}
I think the problem is in const char * arr[] and I changed it,but the problem remains.
You didn't allocate any memory for noFilledStr, so its value is indeterminate and strcat(noFilledStr, tmp) is undefined.
Use malloc to allocate memory and initialize noFilledStr with the returned pointer:
char* noFilledStr = malloc(number_of_bytes);
The strings in arr are char[4], not char[3] (do not forget the null byte!). tmp is too small to hold them, so strcpy(tmp, arr[i]) writes out of bounds.
You are trying to build the string to return in the location pointed to by nofilledStr but this pointer is pointing somewhere as you do not initialize it. You could use a sufficiently large static char[] array if you do not have to deal with multiple threads. Otherwise, use malloc() and require the caller to free() the returned string when he is done with it.
My code does not work. I get run time error at the moment i accept a string. What is the problem with this code?
//this is what i have in main()
char *ele,*s[max];
int *count,temp=0;
count=&temp;
printf("Enter string to insert: ");
scanf("%s",ele);
addleft(s,ele,count);
//following is the function definition
void addleft(char *s[max],char *ele,int *count)
{
int i;
if((*count)==max)
{
printf("Queue full!\n");
return;
}
for(i=*count;i>0;i--)
strcpy(s[i],s[i-1]);
strcpy(s[0],ele);
(*count)++;
printf("String inserted at left!\n");
}
ele is an uninitialised char* and has no memory associated with it and scanf() will be attempting to write to it causing undefined behaviour, a segmentation fault is probable.
You need to either dynamically allocate memory for ele or declare a local array and prevent buffer overrun when using scanf():
char ele[1024];
if (1 == scanf("%1023s", ele))
{
/* Process 'ele'. */
}
Additionally, the function addleft() is using strcpy() on s, which is an array of char* and each of the char* in the array is unitialised. This is undefined behaviour and a probable segmentation fault. To correct, you could use strdup() if it is available otherwise malloc() and strcpy():
/* Instead of:
strcpy(s[0],ele);
use:
*/
s[0] = strdup(ele);
Note that the for loop inside the addleft() function is dangerous as the char* contained within s are not necessarily of the same length. This could easily lead to writing beyond the end of arrays. However, as the elements are addresses of dynamically allocated char* you can just swap the elements instead of copying their content.
sscanf("%s", ele) is putting the input in the memory pointed to by 'ele'. But 'ele' has never been initialized to point to anything. Something like:
char ele[128];
or
char* ele = malloc(...)
should fix it up.
You are causing a buffer overflow because the pointer ele is not pointing to any allocated memory. You are writing into memory that your program needs to run, therefore crashing it. I recommend you implement mallocinto your program like this:
char *ele;
if (!(ele = malloc(50))) //allocate 50 bytes of memory
{
//allocation failed
exit(0);
}
scanf("%s", ele); //string can hold 50 bytes now
free(ele); //free allocated space
You might want to read up on the malloc function here
An easier route would just to make ele an array instead of a pointer:
char ele[50]; //ele is an array of 50 bytes
I'm working my way in understanding pointers. I wrote this string copy functionality in C.
#include<stdio.h>
char *my_strcpy(char *dest, char *source)
{
while (*source != '\0')
{
*dest++ = *source++;
}
*dest = '\0';
return dest;
}
int main(void)
{
char* temp="temp";
char* temp1=NULL;
my_strcpy(temp1,temp);
puts(temp1);
return 0;
}
This program gives a segfault.If I change char* temp1=NULL to char* temp1 still it fails. If I change char* temp1 to char temp1[80], the code works. The code also works if char temp1[1] and gives the output as temp. I was thinking the output should be t. Why is it like this and why do I get error with char* temp.
Because you're not allocating space for the destination string. You're trying to write to memory at position NULL (almost certainly 0x00).
Try char* temp1= malloc(strlen(temp)+1); or something like it. That will allocate some memory and then you can copy the characters into it. The +1 is for the trailing null character.
If you wrote Java and friends, it would prevent you from accessing memory off the end of the array. But at a language level, C lets you write to memory anywhere you want. And then crash (hopefully immediately but maybe next week). Arrays aren't strictly enforced data types, they are just conventions for allocating and referencing memory.
If you create it as char temp1[1] then you are allocating some memory on the stack. Memory near that may be accessible (you can read and write to it) but you will be scribbling over other memory intended for something else. This is a classic memory bug.
Also style: I personally advise against using the return values from ++s. It's harder to read and makes you think twice.
*dest = *source;
dest++;
source++;
Is clearer. But that's just my opinion.
You must to allocate space for the destination parameter.
When you use char temp1[80], you allocate 80 bytes in the memory.
You can allocate memory in static way, like array, or use the malloc function