realloc fails segfault

Started by
12 comments, last by SiCrane 15 years, 4 months ago

//Written in C not C++
#include <stdio.h>
#include <stdlib.h>

struct StudentInfo{
	char* name;
	unsigned int roll;
};

typedef struct StudentInfo StdInfo;

int main(int argc, char** argv){
	StdInfo* students;
	unsigned int size = 3, i=0;
	unsigned short int s = 1;

	students = malloc( size*sizeof(StdInfo) );

	do{
		printf("Enter name of Student %d :\t", i);
		scanf("%s", &(students.name));
		printf("Enter Roll of Student %d :\t", i);
		scanf("%d", &(students.roll));
		printf("\n\nEnter another ? (1/0):\t");
		scanf("%d", &s);
		if(s == 1){
			size *= 2;
			students = realloc( students, size*sizeof(StdInfo) );
		}
		i++;
	}while(s == 1);

	free(students);
	students = 0x0;

	return 0;
}

Why does the above code makes segfault ??
Advertisement
You never allocate memory for the name.
So how can I solve it ??
Quote:Original post by nlbs
So how can I solve it ??
Allocate space for the name.

After students = malloc( size*sizeof(StdInfo) );, add:
for(i=0; i<size; ++i)   students .name = malloc(256);

That'll let you enter up to 255 character names. If you want to completely prevent buffer overruns, you'll need to use some function other than scanf.

EDIT: And you'll need to reallocate the name buffers accordingly, and free them at shutdown. Yet another reason to prefer C++...
Allocate memory for the name.
I think realloc is making the crash.
as even if I remove the char* name from the structure it crashes.
#include <stdio.h>#include <stdlib.h>#include <string.h>struct StudentInfo{	//char* name;	unsigned int roll;};typedef struct StudentInfo StdInfo;int main(int argc, char** argv){	StdInfo* students;	unsigned int size = 3, i=0, j;	unsigned short int s = 1;	char* dump_name;	students = malloc( size*sizeof(StdInfo) );	do{		//StudentInfo.name removed		printf("Enter Roll of Student %d :\t", i);		scanf("%d", &(students.roll));		printf("\n\nEnter another ? (1/0):\t");		scanf("%d", &s);		if(s == 1){			size *= 2;			students = realloc( students, size*sizeof(StdInfo) );		}		i++;	}while(s == 1);	free(students);	students = 0x0;	return 0;}
This one also crashes.
The only other problem I see with that code is that you're using %d to fill a short, which will treat the pointer as a pointer to int, probably causing stack corruption.
I dont think its a problem cause language supports coertion for int to short int.
however can you provide a Solution ??
Quote:Original post by nlbs
I dont think its a problem cause language supports coertion for int to short int.
This is true for simple assignment, but it isn't true for pointers - especially in the case of printf (or any other variadic function), because it recieves no type information at all, beyond the specifiers in the format string.
Quote:however can you provide a Solution ??
Check the man page for printf to find the format specifier for short - I don't recall it offhand. A better solution would be to make s an int anyway, or even better a size_t (which is the type expected by malloc/realloc in most implementations) and use the format specifier for size_t (again, check the man page).

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Quote:Original post by nlbs
I dont think its a problem cause language supports coertion for int to short int.

The language lets you convert between the two types, but printf uses the ellipsis construct. This means no automatic conversion takes place, and you need to tell printf the exact type you passed.

Otherwise, it's similar to casting from (short*) to (int*) -- both C and C++ force you to make an explicit cast to do so, because it isn't safe.

This is one of the reasons that, when programming in C++, we always recommend alternatives to printf -- type safe alternatives such as boost::format, or anything else using operator chaining, where your reasoning wouldn't fall flat, and any necessary conversions would be made for you.

This topic is closed to new replies.

Advertisement