segmentation fault during execution - c

#include<stdio.h>
int main()
{
char *arg[10],*c;
int count=0;
FILE *fp,*fq;
printf("Name of the file:");
scanf("%s",arg[1]);
fp=fopen(arg[1],"w");
printf("\t\t%s",arg[1]);
printf("Input the text into the file\n");
printf("Press Ctrl+d to the stop\n");
while((*c=getchar())!=EOF)
{
fwrite(c,sizeof(char),1,fp);
count++;
}
return 0;
}

Change this line
char *arg[10],*c;
to
char arg[1000],c;
This line
scanf("%s",arg[1]);
to
scanf("%s",arg);
And this line
while((*c=getchar())!=EOF)
to
while((c=getchar())!=EOF)
Explanation:
char *c; is not a character. It's a pointer to a character. It starts out just pointing to a random bit of memory, which will often be filled with random data - whatever was most recently written there.
char c; is a character.
The same thing applies to char *arg[10]. It's an array of ten pointers. They point into random memory, filled with random data.
Note: my change is not best practice. If someone were to type in a filename 1000 characters or more long, you'd write over the end of the arg buffer. Depending on what you're doing, this can be a security bug.

In
char *arg[10];
you define an array of 10 pointers to char but you do not initialize its elements. arg[0], arg[1], ..., arg[9] will all have undefined values.
Then, you try to enter a string into one of those undefined values. Lucky you, you got a segmentation fault. Had you been unlucky, your program could format your hard disk instead.

char *arg[10] ;
arg is array of char pointers. You need to assign them memory locations using malloc before taking input -
scanf("%s",arg[1]); // arg[1] is not assigned to point to any memory location
// and is what causing the segmentation fault.
So do -
arg[1] = malloc( stringLengthExpectedToEnter + 1 ) ; // +1 for termination character
Should do like that with the rest of array elements too (or) simply change char*arg[10] to char arg[10] and make sure to enter only enter 9 characters.
I think you are confusing between a pointer and a normal variable.
int *ptr;
ptr is variable that can hold the address of an integer variable. Memory is allocated to for ptr variable to hold an integer address. That's it. ptr is in an uninitalized state and is pointing no where (or) might be pointing to garbage. Dereferencing an uninitialized pointer's behavior is undefined and you are lucky enough if it gives a segmentation-fault.
Now, you need to assign it a valid memory location using malloc.
ptr = malloc( sizeof(int) ) ; // Allocates number of bytes required to hold an
// integer and returns it's address.
So, ptr is now pointing to memory location acquired from free store that can hold an integer. Such acquired locations from free stored must be freed using free, else you have classical problem of memory leak. It is good practice to initialize pointer to NULL while declaration.
int *ptr = NULL ;
Hope it helps !
scanf("%d", ptr) ; // Notice that & is not required before ptr. Because ptr
// content is address itself.
A normal variable story is entirely different. When declared -
int var ;
Memory is allocated to var to hold an integer. So, you can directly assign it an integer.

#include<stdio.h>
int main()
{
char arg[10],c;
int count=0;
FILE *fp;
printf("Name of the file:");
scanf("%s",arg);
fp=fopen(arg,"w");
printf("\t\t%s",arg);
printf("Input the text into the file\n");
printf("Press Ctrl+d to the stop\n");
while((c=getchar())!=EOF)
{
fwrite(&c,sizeof(char),1,fp);
count++;
}
if(fp != NULL){
fclose(fp);
fp = NULL;
}
return 0;
}

Related

puts function gives garbage value in C

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;
...

Same structure objects memory overlap?

struct integer
{
int len;
char* str;
int* arr;
}int1, int2;
int main(void) {
printf("Please enter 1st number\n");
int1.str= str_input();
int1.len=chars_read-1;
int1.arr= func2(int1.len, int1.str);
printf(("\%c\n"), *int1.str);
printf("Please enter 2nd number\n");
int2.str = str_input();
int2.len=chars_read-1;
printf(("\n %c\n"), *int1.str );
int2.arr= func2(int2.len, int2.str);
if the input is 4363 and 78596 , the output is 4 and 7 respectively.
The output is not 4 and 4. Given that both are different objects, shouldn't both have different memory allocation?
Please note: this is NOT a typographical error. I have used the same *int1.str both times. the problem is that although I have made no changes in it, its value is changing. How?
I do not think that str_input() can make a difference.
char* str_input(void) {
char cur_char;
char* input_ptr = (char*)malloc(LINE_LEN * sizeof(char));
char input_string[LINE_LEN];
//while ((cur_char = getchar()) != '\n' && cur_char<='9' && cur_char>='0' && chars_read < 10000)
for(chars_read=1; chars_read<10000; chars_read++)
{
scanf("%c", &cur_char);
if(cur_char!='\n' && cur_char<='9' && cur_char>='0')
{
input_string[chars_read-1]= cur_char;
printf("%c\n", input_string[chars_read-1]);
}
else{
break;
}
}
input_string[chars_read] = '\n';
input_ptr = &input_string[0]; /* sets pointer to address of 0th index */
return input_ptr;
}
//chars_read is a global variable.
Thanks in advance.
you have printed the same variable, *int1.str
It will be helpful have the source code of str_input(), but it's probably that it returns a pointer to the same buffer in each call, so the second call to str_input() updates also the target of int1.str (beacuse it's pointing to the same char* than int2.str)
As noted elsewhere, both of the printf calls in your question pass *int1.str to printf.
However, if that is merely a typographical error in your question, and the second printf call passes *int2.str, then most likely the problem is that str_input returns the address of a fixed buffer (with static or, worse, automatic storage duration). Instead, str_input should use malloc or strdup to allocate new memory for each string and should return a pointer to that. Then the caller should free the memory.
Alternatively, str_input may be changed to accept a buffer and size passed to it by the caller, and the caller will have the responsibility of providing a different buffer for each call.
About the newly posted code
The code for str_input contains this line:
char* input_ptr = (char*)malloc(LINE_LEN * sizeof(char));
That declares input_ptr to be a char * and calls malloc to get space. Then input_ptr is set to contain the address of that space. Later, str_input contains this line:
input_ptr = &input_string[0];
That line completely ignores the prior value of input_ptr and overwrites it with the address of input_string[0]. So the address returned by malloc is gone. The str_input function returns the address of input_string[0] each time it is called. This is wrong. str_input must return the address of the allocated space each time.
Typically, a routine like this would use input_ptr throughout, doing its work in the char array at that address. It would not use a separate array, input_string, for its work. So delete the definition of input_string and change str_input to do all its work in the space pointed to by input_ptr.
Also, do not set the size of the buffer to LINE_LEN in one place but limit the number of characters in it with chars_read < 10000. Use the same limit in all places. Also allow one byte for a null character at the end (unless you are very careful never to perform any operation that requires a null byte at the end).

Taking string input in char pointer

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
char *s;
printf("enter the string : ");
scanf("%s", s);
printf("you entered %s\n", s);
return 0;
}
When I provide small inputs of length up to 17 characters (for example "aaaaaaaaaaaaaaaaa") the program works perfectly fine but on providing inputs of larger lengths, it gives me a runtime error saying "main.c has stopped working unexpectedly".
Is there some problem with my compiler (codeblocks) or my pc (windows 7)? Or is it somehow related to the input buffer of C?
It's undefined behaviour as the pointer is uninitialized. There's no problem with your compiler but your code has problem :)
Make s point to valid memory before storing data in there.
To manage buffer overflow, you can specify the length in the format specifier:
scanf("%255s", s); // If s holds a memory of 256 bytes
// '255' should be modified as per the memory allocated.
GNU C supports an non-standard extension with which you don't have to allocate memory as allocation is done if %as is specified but a pointer to pointer should be passed:
#include<stdio.h>
#include<stdlib.h>
int main() {
char *s,*p;
s = malloc(256);
scanf("%255s", s); // Don't read more than 255 chars
printf("%s", s);
// No need to malloc `p` here
scanf("%as", &p); // GNU C library supports this type of allocate and store.
printf("%s", p);
free(s);
free(p);
return 0;
}
the char pointer is not initialized, you should dynamiclly allocate memory to it,
char *s = malloc(sizeof(char) * N);
where N is the maximum string size you can read, And its not safe to use scanf
without specifying the maximum length for the input string, use it like this,
scanf("%Ns",s);
where N same as that for malloc.
You are not allocating any memory to the character array so first try to get memory by calling malloc() or calloc(). then try to use it.
s = malloc(sizeof(char) * YOUR_ARRAY_SIZE);
...do your work...
free(s);
You need to allocate enough memory for buffer where your pointer will point to:
s = malloc(sizeof(char) * BUF_LEN);
and then free this memory if you do not need it anymore:
free(s);
You're not allocating memory for your string, and thus, you're trying to write in a non-authorized memory address. Here
char *s;
You're just declaring a pointer. You're not specifying how much memory to reserve for your string. You can statically declare this like:
char s[100];
which will reserve 100 characters. If you go beyond 100, it will still crash as you mentionned for the same reason again.
The problem is with your code .. you never allocate memory for the char *. Since, there is no memory allocated(with malloc()) big enough to hold the string, this becomes an undefined behavior..
You must allocate memory for s and then use scanf()(I prefer fgets())
#include"stdio.h"
#include"malloc.h"
int main(){
char *str;
str=(char*)malloc(sizeof(char)*30);
printf("\nENTER THE STRING : ");
fgets(str,30,stdin);
printf("\nSTRING IS : %s",str);
return 0;
}
The code in C to read a character pointer
#include<stdio.h>
#include<stdlib.h>
void main()
{
char* str1;//a character pointer is created
str1 = (char*)malloc(sizeof(char)*100);//allocating memory to pointer
scanf("%[^\n]s",str1);//hence the memory is allocated now we can store the characters in allocated memory space
printf("%s",str1);
free(str1);//free the memory allocated to the pointer
}
I was getting this problem. I tried this code below and it worked:
char *text;
scanf("%s", *&text);
I dont know how it worked. I just felt like doing it.

ERROR READING STRING

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

Dereferencing a double pointer and using index operator

I am passing a double pointer of type char ** to a function. Inside that function, I need to dereference the pointer and then index through the character array.
Unfortunately, I am getting a core dump when I try to assign a capital letter back into the array.
I need help on how to do this. (This is not homework, just a personal project.)
void buffer(char **ppline);
int main()
{
char *line="The redcoats are coming!";
buffer(&line);
printf("\nline = %s\n",line);
return(0);
}
void buffer (char **ppline)
{
int i=0;
char a;
for (i=0; i < strlen(*ppline); i++)
{
a = toupper( (*ppline)[i] ); /* THIS LINE CAUSES THE CORE DUMP */
((*ppline)[i]) = a;
}
return;
}
A string literal in "" is constant. You cannot modify it as you're doing, as that is undefined behavior. Try this, which allocates storage and copies the string literal into it:
void buffer(char **ppline);
int main()
{
char line[] = "The redcoats are coming!";
buffer(&line);
printf("\nline = %s\n",line);
return(0);
}
void buffer (char **ppline)
{
int i=0;
char a;
for (i=0; i < strlen(*ppline); i++)
{
a = toupper( (*ppline)[i] ); /* THIS LINE CAUSES THE CORE DUMP */
((*ppline)[i]) = a;
}
return;
}
Stack, heap, datasegment(and BSS) and text segement are the four segments of process memory. All the local variables defined will be in stack. Dynmically allocated memory using malloc and calloc will be in heap. All the global and static variables will be in data segment. Text segment will have the assembly code of the program and some constants.
In these 4 segements, text segment is the READ ONLY segment and in the all the other three is for READ and WRITE.
char []a="The redcoats are coming!"; - This statemnt will allocate memory for 25 bytes in stack(because local variable) and it will keep all the 24 characters plus NULL character (\0) at the end.
char *p="The redcoats are coming!"; - This statement will allocate memory for 4 bytes(if it is 32 bit machine) in stack(because this is also a local variable) and it will hold the pointer of the constant string which value is "The redcoats are coming!". This byte of constant string will be in text segment. This is a constant value. Pointer variable p just points to that string.
Now a[0] (index can be 0 to 24) means, it will access first character of that string which is in stack. So we can do write also at this position. a[0] = 'x' This operation is allowed because we have READ WRITE access in stack.
But p[0] = 'x' will leads to crash, because we have only READ access to text segement. Segmentation fault will happen if we do any write on text segment.
But you can change the value of variable p, because its local variable in stack. like below
char *p = "string";
printf("%s", p);
p = "start";
printf("%s", p);
This is allowed. Here we are changing the address stored in the pointer variable p to address of the string start(again start is also a read only data in text segement). If you want to modify values present in *p means go for dynamically allocated memory.
char *p = NULL;
p = malloc(sizeof(char)*7);
strcpy(p, "string");
Now p[0] = 'x' operation is allowed, because now we are writing in heap.

Resources