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.
Related
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... ;-)
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.
Curious about what is going wrong with this strcpy.
int main(void){
char *history[10];
for(int i = 0; i < 10; i++){
history[i] = NULL;
}
char line[80];
fgets(line,80,stdin);
strcpy(history[0],line); //This line segfaults
}
You've created an array of NULL pointers. You then tried to copy characters onto NULL. That's a no-no.
EDIT:
Your program could be optimized to this:
void main() {
char line[80];
fgets(line,80,stdin);
}
Your history array is never used to generate any output. So, while others have pointed out you need to allocate memory, technically, you could simply do this:
history[0] = line;
That will be a valid pointer up until the line goes out of scope, which is when history goes out of scope so it won't matter.
You need to allocate memory for history[0]. As history[0] is assigned NULL referencing it or writing to it will/may cause segfault.
something like
//this will create memory for 100 chars
history[0] = malloc(sizeof(char) * 100);
strcpy(history[0],line);
Or
//shortcut for both - this allocate new memory and returns pointer.
history[0] = strdup(line);
I get a segmentation fault each time I'm trying to run this function.
char *hist_array[20];
int history_counter = 0;
void save_to_history(char *temp){
temp = malloc(512);/*512 is the size of temp array*/
printf("temp = %s\narray = %s",temp,hist_array[history_counter]);/*debug*/
strcpy(hist_array[history_counter],temp);
printf("Saved %s to history to %d\n\n",hist_array[history_counter],history_counter);
history_counter++;
}
I'm not sure whether I'm using malloc correctly or not, but as I understand it should help with properly saving my string temp to an array of strings hist_array. Also, temp is never NULL.
EDIT 1: Changed sizeof(temp) to its proper size 512, still getting segfault.
The problem is with the following statement -
strcpy(hist_array[history_counter], temp);
strcpy tries to copy the buffer pointed to by temp to the buffer pointed to by hist_array[history_counter] but char *hist_array[20]; defines hist_array to be an array of 20 pointers to characters. You should change your function to -
char *hist_array[20];
int history_counter = 0;
void save_to_history(char *temp) {
// +1 for the terminating null byte as strlen
// does not count the null byte
hist_array[history_counter] = malloc(1 + strlen(temp));
if(hist_array[history_counter] == NULL) {
printf("not enough memory to allocate\n");
// handle it
}
strcpy(hist_array[history_counter], temp);
printf("Saved %s to history to %d\n\n",
hist_array[history_counter],
history_counter);
history_counter++;
}
In your code, you are allocating via malloc but you don't initialize it. So when you do this:
printf("temp = %s\narray = %s",temp,hist_array[history_counter]);/*debug*/
strcpy(hist_array[history_counter],temp);
The should print some garbage and the subsequent strcpy will copy whatever is in temp at the time, until it encounters a 0 byte. You are invoking undefined behaviour here, because you should initialize the memory.
For example you could do:
memset(temp, 0, 512);
Additionally you are dereferencing pointers in your array hist_array. Since this is a global variable, all the pointers will originally be NULL pointers, which is causing your segfaul there.
Have a
typedef struct person {
char name[20]
char surname[20]
} person_t;
I need to create a string like XXXXXX:YYYYYY with the function like
char* personToString(person_t *p). I tried to make it:
char* personToString(person_t* p) {
int n1,n2;
n1=strlen(p->name);
n2=strlen(p->surname);
char *p = (char*) malloc((n1+n2+2)*sizeof(char));
strcat(p,puser->name);
strcat(p,":");
strcat(p,puser->surname);
return p;
}
This give me a reasonable output but I have some errors testing with valgrind! I also think that there is a way more classy to write the function!
When you malloc memory for p the memory will hold garbage values. Strcat will append a string after the null character, but in an uninitialized string will hold random values.
Replace the first strcat with strcpy.
You need to
strcpy(p,puser->name);
not
strcat(p,puser->name);
malloc does not initialize the buffer to zero, so strcat is searching for a null byte in p first and probably not finding one, reading past the end of the buffer and thus crashing.
Instead of one strcpy plus two strcat you can also write one call to sprintf:
sprintf(p, "%s:%s", puser->name, puser->surname);
First you should call string copy, then strcat:
strcat(p,puser->name);
should be:
strcpy(p,puser->name);
because memory allocated with malloc function keeps values garbage, by doing strcat for first you are concatenating after garbage -- it also brings Undefined behaviour in your code.
You can use void* calloc (size_t num, size_t size); instead of malloc(), calloc function initialized allocated memory with 0 (then strcat() no problem).
Also dynamically allocated memory you should deallocate memory block using void free (void* ptr);) explicitly.
This looks good to me,
char* personToString( struct person_t *p )
{
int len = strlen(p->name) + strlen(p->surname) + 2; // holds ':' + NULL
char *str = malloc( len ); // Never cast malloc's return value in C
// Check str for NULL
if( str == NULL )
{
// we are out of memory
// handle errors
return NULL;
}
snprintf( str, len, "%s:%s", p->name, p->surname);
return str;
}
NOTE:
Never cast malloc's return value in C.
Use snprintf when multiple strcat is needed, its elegant.
free the return value str here in caller.
Fixed struct and char variables.