While I was inputting "stuList[1].name", an error occurred and the program crashed. How do I fix this?
#include <stdio.h>
#include <conio.h>
typedef struct student
{
int id;
char *name;
float percentage;
} student;
int main()
{
student stuList[3];
stuList[0].name = "vermidonhapic";
stuList[2].name = "didiervermiyer";
scanf("%s\n",&stuList[1].name);
printf(" name is: %s \n", stuList[0].name);
printf(" name is: %s \n", stuList[2].name);
printf(" name is: %s \n", stuList[1].name);
system("PAUSE");
}
In this command: scanf("%s\n",&stuList[1].name);
You are scanning string from input without actually allocating the required memory.
This results in trying to write the data in an unkown address, which is not yours, which results in a segmentation fault.
To fix it, first allocate memory: stuList[1].name = malloc(MAX_LENGTH);, and only after: scan the string from stdin.
name is just a pointer that isn't pointing to memory you own, so writing through it will corrupt memory. You need to allocate some memory on it with malloc(), or make it an array rather than a pointer.
stuList[1].name is an invalid pointer as it has not been initialized to point to a valid object.
You should dynamically allocate memory (through malloc function) for stuList[1].name so scanf could write to an allocated object.
stuList[1].name = malloc(size_enough_to_store_your_string);
Moreover, stuList[1].name is a pointer to char so you should use stuList[1].name and not &stuList[1].name (pointer to a pointer to char) in your scanf function call.
You forgot to allocate memory for stuList[1].name. You need to allocate it from the heap with malloc or stack allocate it.
stuList[1].name = malloc(MAX_NAME_LENGTH);//heap allocation
//use stuList[1].name
free(stuList[1].name);
char buffer[MAX_NAME_LENGTH];//stack allocation
stuList[1].name = buffer;
I've omitted all error checking, protection against over-running buffers etc.
Since stuList[1].name is a pointer, you are incorrect in taking its address in your scanf.
Related
This question already has answers here:
What is the difference between char s[] and char *s?
(14 answers)
Closed 7 years ago.
First version: (Works)
//Using sprintf
int index = 56;
char filename[64], * suffix = "txt";
sprintf(filename, "log_%d.%s", index, suffix);
lr_output_message ("The new file name is %s", filename);
//This works
Second version: (Does not work)
//Using sprintf
int index = 56;
char *filename, * suffix = "txt";
sprintf(filename, "log_%d.%s", index, suffix);
lr_output_message ("The new file name is %s", filename);
//Fails with invalid parameter passed to function
Your first version (is correct and) works, because there is (enough) memory allocated for filename, which is a char array.
char filename[64]. //....
Your second version (is incorrect and) does not work, because there is no memory allocation for filename, which you define as a pointer.
char *filename,//...
This does not allocate memory to the pointer automatically.
In other words, the pointer is not pointing to any valid memory address. So, trying to access the memory pointed by the pointer is invalid and invokes undefined behaviour.
Solution: You need to allocate memory to the pointer before you use it.
You can use malloc() and family functions to allocate memory to the pointer.
Also, one you allocate memory and the usage is done. you've to release the allocated memory using free()
In the second case you have to allocate space in memory for filename, using malloc()
char *filename = malloc(64);
If you do not allocate space you will have undefined behaviour because of you are writing to a not initialized pointer.
Remember to always check the return of malloc:
if (filename != NULL)
{
// your code ...
}
else
{
printf("No space available for filename");
}
Once you allocate memory and the usage is done. you've to release the allocated memory using free()
This is my struct:
typedef struct Person {
char* name;
int age;
float height;
float weight;
char** hobbies;
}person;
I tried to fill the name but it just ain't working.
void main(){
person Asaf;
char buffer[50];
int length;
puts("Please enter the name of the student");
gets(buffer);
length = strlen(buffer);
Asaf.name = realloc(buffer, length);
}
I just can't figure the problem...
I guess it has something to do with the realloc function.
please help!! :P
You are trying to realloc (which operates on the heap) an array that is allocated on the stack, which is a no-no. What you want instead is something like:
Asaf.name = strdup(buffer); /* POSIX: allocates a string copy of buffer on the heap */
Or, more standardly:
Asaf.name = (char*) malloc(strlen(buffer) + 1); /* TODO: should check allocations for NULL return */
strcpy(Asaf.name, buffer);
Also, you should use fgets() rather than gets(). gets() is inherently dangerous and should never be used because it doesn't do any bounds checking on the array to which it writes.
fgets(buffer, sizeof(buffer), stdin);
This function returns a pointer to the newly allocated memory, or NULL if the request fails.
so as realloc operates on heap here getting pointer to the memory allocation in heap area to a pointer guy sitting in stack can cause some problems buddy.
so maybe undefined behavior can be the answer for the output you are getting.
About how using realloc, all the didactic examples include this-
Use realloc:
1>Check if it's NULL.In this case use perror and exit the program
2>If it's not NULL use the memory allocated
3>Free the memory when you don't need it anymore.
possible duplicate of:How to use realloc in a function in C
#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.
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 am trying to write this code, but it gives me segmentation fault after running the program, could you please help to sort it out?
#include <stdio.h>
#include <string.h>
typedef struct{
int salary;
char* name;
} employee ;
int main(){
employee p[2];
int i;
for(i=0;i<2; i++){
printf("enter sal ");
scanf("%d", &p[i].salary);
printf("enter name ");
scanf("%s", &p[i].name);
}
for(i=0;i<2; i++){
printf("p %d",p[i].salary);
printf("p %s",p[i].name);
}
return 0;
}
You need to allocate memory for the name field: p[i].name = (char*)malloc(MAX_NAME_LEN)
Also, the scanf("%s", &p[i].name) should read scanf("%s", p[i].name).
The structure field name is just a wild character pointer.
char* name;
you are reading the user input as:
scanf("%s", &p[i].name);
into the memory pointed by name which could be anywhere.
To fix this you need to dynamically allocate memory pointed to by name or you can change name to a char array of size one greater than the max length of the name possible.
char name[MAX];
You don't need the & operator when scanf'ing to pointer. And you need to malloc p[i].name
scanf("%s", p[i].name);
You are not allocating memory for char* name. change your data structure to
typedef struct
{
int salary;
char name[50];
}
or allocate memory using malloc
You forgot to allocate memory for p[i].name.
You have to reserve memory for the name member of each instance of employee:
p[i].name = (char*)malloc(expected_max_size);
just before the scanf for that variable. Declaring a pointer to char char* does not assign memory for the actual string pointed to, but just for the pointer itself, and in your example it is not initialized. By using malloc you reserve a piece of memory and makes the pointer point to it. You have to be careful with bounds checking, because you have to reserve the memory beforehand, enough to hold what the user is writing.
You need to allocate memory for the "name" string in your structure. Do this using malloc() or by declaring name as an array of a given size (char name[SIZE]).