SIZE = 2*1024*1024*1024;
struct
{
char array[SIZE];
} s1;
char *seq;
File *sp;
int i = 0;
EoFReached = 0;
memset(array,0,SIZE*sizeof(char));
while(EoFReached == 0) {
getseq(sp, seq, EoFReached);
memcpy(&(s1->array[i]),seq, seqlen);
i = i + seqlen;
}
After i value of 630511104 memcpy overwrites some values with some wrong values in the beginning of the array itself but at same time ending values are correct.
So tired to allocate memory dynamically instead of static allocation, using malloc.
But got segmentation falut after 630511104
with error message in gdb as
__memcpy_ssse3 () at ..sysdeps/x86_64/multiarch/memcpy-ssse3.S:"
../sysdeps/x86_64/multiarch/memcpy-ssse3.S: No such file or
directory.
You put the 2 gig big s1 on the stack wich is not that big. Try to allocate s1 with new instead:
struct fred { char array[SIZE]; }; fred * s1 = new fred;
Related
I have to dynamically allocate memory using these two functions but I keep getting a segfault. The code takes in strings from a file. I need to dynamically allocate memory for a specific number of monsters using structs, pointers and malloc.
typedef struct monster {
char *name;
char *element;
int population;
} monster;
monster* createMonster(char *name, char *element, int population){
//Copying the data into the monster
monster *temp =(monster*) malloc(sizeof(monster));
strcpy(temp->name, name);
strcpy(temp->element, element);
strcpy(temp->population, population);
return temp;
free(temp);
}
monster** readMonsters(FILE* infile, int *monsterCount){
//getting monster count and creating temp pointers
monster **temp = NULL;
char m_word [8];
fscanf(infile, "%d", monsterCount);
fscanf(infile, "%s", m_word); //reading the word monster to skip it
char* temp_name;
char* temp_element;
int temp_pop;
//allocating memory and creating an array of monster pointers * mcount
temp = (monster**)malloc(*monsterCount * sizeof(monster*));
for(int i = 0; i < monsterCount; i++){
fscanf(infile, "%s",temp_name);
fscanf(infile, "%s",temp_element);
fscanf(infile, "%d",temp_pop);
monster *monster_temp = createMonster(temp_name, temp_element, temp_pop);
temp[i]->name = monster_temp->name;
temp[i]->element = monster_temp->element;
temp[i]->population = monster_temp->population;
}
return temp;
}
You haven't posted the definition of struct monster.
If struct monster contains a lot of char* and you are assigning a char* to it, that char* needs to be allocated somewhere. It doesn't look like temp_name and temp_element have been allocated, which would cause a crash on the scanf.
your code segfault because you write at uninitialized and unallocated pointers
you directly write with strcpy name and element field of your struct but these two field point at unknow location
also, you try strcpy an integer, directly assign it : temp->population = population ;
finally you cannot return temp and free temp, if you return it it will be reused, you must not free it, hopefully the free is never reach as you exit the function one line before :)
for storing your strings into the struct, you have some possibilities
declare them as array of char in your structure : char name[64]
use a buffer in your structure and set the name and element field point on part of it
malloc them with strlen of original strings before the copy
directly point name and element vars of your createMonster function to the pointer, it will use original memory, but it's not suitable here as they come from temporary memory
an example of create monster function using a static common buffer for your strings (untested) :
#define MONSTER_MAX_BF 64
typedef struct monster {
char *name;
char *element;
int population;
char bf[MONSTER_MAX_BF];
} monster;
monster* createMonster(char *name, char *element, int population){
monster *temp =(monster*) malloc(sizeof(monster));
char * lastBf = temp->bf + (MONSTER_MAX_BF - 1); // buffer last char
char *bfp = bf, *p ;
// copy name
temp->name = bfp ;
p = name ;
while( *p && *bfp != lastBf ) *bfp++ = *p++ ;
*bfp++ = 0;
// copy element
temp->element = bfp ;
p = element ;
while( *p && *bfp != lastBf ) *bfp++ = *p++ ;
*bfp = 0;
temp->population = population ;
return temp;
}
I'm encountering a segmentation fault in my program and I'm pretty sure it's a silly mistake! When I try to access data in my arrays of structs I get a segemtentation fault.
struct block {
int validBit;
int tag;
unsigned long data;
};
typedef struct block block_t;
struct set{
block_t *blocks;
int tst;
};
typedef struct set set_t;
struct cache{
//bunch of variables I have left out for this question
set_t *set;
};
typedef struct cache cache_t;
So the allocation of memory to these are
cache_t *cache = NULL;
cache = malloc(sizeof(*cache);
if(cache == NULL){
fprintf(stdout,"Could not allocate memory for cache!");
}
cache->set = malloc(16 * sizeof(*cache->set));
if(cache->set == NULL){
fprintf(stdout,"Could not allocate memory for cache->set!");
}
cache->set->blocks = malloc(2 * sizeof(*cache->set->blocks));
if(cache->set->blocks == NULL){
fprintf(stdout,"Could not allocate memory for cache->set->blocks!");
}
The cache holds an array of sets with 16 elements. The cache->sets holds an array of blocks with 2 elements.
When I try to set the value of variables inside a block struct a segmentation error arises.
cache->set[0].blocks[0].tag = 1; //This works
cache->set[0].blocks[1].tag = 2; //This works
cache->set[1].blocks[0].tag = 3; //Segmentation fault
EDIT: It seems there is a problem with the variable "tag" inside blocks. If i assign a value to validbit in set[1] it does not produce a segmentation fault.
cache->set[1].blocks[0].validBit = 3; // This works
cache->set[1].blocks[0].tag = 3; //does not work
So it seems to be an issue with the tag variable? Makes no sense to me
Thanks in advance :)
You are not allocating memory for your "block_t" beyond set[0].
Roughly, you should be doing something along these lines:
cache = malloc(sizeof *cache);
cache->set = malloc(num_sets * sizeof *cache->set);
for (i = 0; i < num_sets; i++) {
cache->set[i].blocks = malloc(...);
}
I am new to c programming and I am stuck with this one its a typedef struct and what I would like to do is that I want to create an array from the double pointer from this structure
typedef struct
{
char* firstname;
float price;
}Name,*pName,**ppName;
typedef struct
{
ppName Names;
unsigned int numPerson;
}Book;
And my main which always give me segmentation fault dont mind the loop it is looping until the use says to quit.
int main(void)
{
Book D;
setUpCollection(&D);
while(..)
{
scanf(...);
switch(...)
{
case 1:
if(!AddNewPerson(&D))
return 1;
break;
case 2:
....
case 3:
....
default:
printf("Please enter a valid choice");
}
}
return 0;
}
void setUpCollection(Book* data){
Name name;
pName pname;
pname= malloc(MAX_PERSON* sizeof(pName));
pname= &name;
data->Names= &pname;
data->numPerson= 0;
}
BOOL AddNewPerson(Book* data){
char *title = malloc(sizeof(char));
int len;
Name name;
pName pname;
scanf(...);
len = strlen(firstname);
name.firstname = malloc(len * sizeof(char*));
name.firstname = firstname;
pname= malloc(1);
pname= &name;
data->DVDs[data->numPerson++] = pname;
printf("%0.2f", data->Names[(data->numPerson)-1]->price);
return TRUE;
}
My main problem is that I cant print all the added names and also getting segmentation fault.
There are quite a few errors in your program but let me mention a few:
Doesn't this seem odd to you:
pname= malloc(MAX_PERSON* sizeof(pName));
pname= &name;
you are creating a memory leak by first letting pname point to the array of pName then assigning to &name.
What is this:
char *title = malloc(sizeof(char)); // ?
here you allocate too less space
name.firstname = malloc(len * sizeof(char*));
it should be
name.firstname = malloc(len * sizeof(char) + 1);
or more readable:
name.firstname = malloc(len+1);
this makes no sense again:
pname= malloc(1);
pname= &name;
again you created a memory leak by first letting pname point to a heap block of 1 byte then assigning it to a local variable which you include in data - the local variable is freed up once you leave AddNewPerson() so data will point to garbage.
Instead do something like this (I am no fan of having
typedefs for pointers), also try avoiding naming types
the same way you name variables for clarity:
typedef struct
{
char *firstname;
float price;
} Name;
typedef struct
{
Name** names;
unsigned int numPerson;
} Book;
Now allocate the initial size of your array, the whole point
of having it on the heap is that the array can grow if more
records are added than MAX_PERSONS so you need to keep track
of the number of used records in the array as well as the number
of records allocated
int allocated = MAX_PERSONS;
Book D;
D.names = malloc( allocated * sizeof(Name*) );
D.numPerson = 0;
then loop over user input and add records keeping
track of how many records have been read. Since names
is an array of pointers, you need to allocate a Name
struct each time you add an entry
e.g.
D.names[i] = malloc( sizeof(Name) );
D.names[i]->firstname = strdup(userInputName);
D.names[i]->price = userInputPrice;
then at each iteration check if there is allocated memory left
++i;
if ( i == allocated )
{
// if yes you need to get more memory, use realloc for that
// get e.g. 10 more records
Name* tmp = realloc( D.names, (allocated + 10)*sizeof(Name) );
if ( tmp != NULL )
{
D.names = tmp;
allocated += 10;
}
else
{ .. some error msg .. }
}
I have pasted the code here, at the statement *stack_ptr->s3++ = element;
segmentation fault is occurring. Can you please let me know what should I change to eliminate the error?
typedef int stack_elmnt_int;
typedef struct {
stack_elmnt *s1;
stack_elmnt_int *s3;
int length;
int top;
} stack;
int push_stack_int(stack *stack_ptr, stack_elmnt_int element)
{
int i=0;
if (stack_full(stack_ptr))
printf("\nStack is full.");
else{
*stack_ptr->s3++ = element;
}
}
void main()
{
int arr[128], arr_num = sizeof(arr)/sizeof(int);
//after input from user to arr
//partial code pasted here
for(i=0;i<arr_num ;i++)
push_stack_int(&stack_1,arr[i]);
}
statement (*stack_ptr->s3++ = element;) segmentation fault is occuring,
Probably you don't allocate memory for s3.
*stack_ptr->s3++ = element;
^
| assigning to garbage location
Can you please let me know what should I change to eliminate the error?
In main() function after declaration of stack_1 allocate memory for s3 ( you should allocate memory for s1 also ), do like:
stack_1.s3 = calloc(MAX_NUMBER_OF_ELEMENT, sizeof( stack_elmnt_int));
Additionally, you should not increment s3 pointer. (you will loss starting address) do like:
stack_ptr->s3[top++] = element;
You need to check that both stack_ptr and stack_ptr->s3 have had memory allocated and been initialized previously in your code.
So I'm trying to learn C right now, and I have some basic struct questions I'd like to clear up:
Basically, everything centers around this snippet of code:
#include <stdio.h>
#include <stdlib.h>
#define MAX_NAME_LEN 127
typedef struct {
char name[MAX_NAME_LEN + 1];
unsigned long sid;
} Student;
/* return the name of student s */
const char* getName (const Student* s) { // the parameter 's' is a pointer to a Student struct
return s->name; // returns the 'name' member of a Student struct
}
/* set the name of student s
If name is too long, cut off characters after the maximum number of characters allowed.
*/
void setName(Student* s, const char* name) { // 's' is a pointer to a Student struct | 'name' is a pointer to the first element of a char array (repres. a string)
char temp;
int i;
for (i = 0, temp = &name; temp != '\0'; temp++, i++) {
*((s->name) + i) = temp;
}
/* return the SID of student s */
unsigned long getStudentID(const Student* s) { // 's' is a pointer to a Student struct
return s->sid;
}
/* set the SID of student s */
void setStudentID(Student* s, unsigned long sid) { // 's' is a pointer to a Student struct | 'sid' is a 'long' representing the desired SID
s->sid = sid;
}
I've commented up the code in an attempt to solidify my understanding of pointers; I hope they're all accurate.
Also, I have another method,
Student* makeAndrew(void) {
Student s;
setName(&s, "Andrew");
setStudentID(&s, 12345678);
return &s;
}
which I'm sure is wrong in some way... I also think my setName is implemented incorrectly.
Any pointers? (no pun intended)
This is very wrong. If you insist on not using strcpy do something like this (not tested)
int iStringLength = strlen(name);
for (i = 0; i < iStringLength; i++) {
s->name[i] = name[i];
}
but make sure that the length is not longer than your array size.
This is also wrong
Student* makeAndrew(void) {
Student s;
setName(&s, "Andrew");
setStudentID(&s, 12345678);
return &s;
}
because the s object is destroyed when the function exits - it is local to the function scope and yet you return a pointer to it. So if you try to access the struct using this pointer it will not be valid as the instance no longer exists. If you want to do this you should dynamically allocate it using malloc . Alternatively do not return a pointer at all and use the alternative option of #Andrew .
In your "another method" you are locally declaring Student s, which will dynamically allocate space (usually on the stack) and you are returning that address on completion.
However, that stack-space will be released on the return, so there is no guarantee that the data is uncorrupted - in fact the likelyhood is that it will be!
Declare Student s in the call to your method, and pass the pointer to makeAndrew:
void makeAndrew(Student *s) {
setName( s, "Andrew");
setStudentID( s, 12345678);
}
...
Student s;
makeAndrew( &s );
...
Your function makeAndrew returns pointer to a local variable. It is only valid before the scope ends, so as soon as the function finishes, it will change when the memory gets overwritten - i. e. almost instantly. You would have to allocate it dynamically (using Student *s = new Student;, or if you really want to stick to pure C, Student *s = malloc (sizeof Student );, and then free it outside the function after it is not needed to avoid memory leak.
Or do it as Andrew suggested, it's less error-prone.
I would change the makeAndrew() function to just return a struct, not a pointer to a struct to correct the error with respect to returning a pointer to a temporary variable:
Student makeAndrew(void)
{
Student s;
setName(&s, "Andrew");
setStudentID(&s, 12345678);
return s;
}
Student aStudent = makeAndrew();
Your setName does have an error with respect to temp, which should be a char *, since you are incrementing it in your loop to point to another character in the input c-string. I think it was missing the null termination as well. And as you mention in your comment, there should be a check for overflow of the name char array in Student:
void setName(Student* s, const char* name) { // 's' is a pointer to a Student struct |
// 'name' is a pointer to the first element of a char array (repres. a string)
const char *temp;
int i;
for (i = 0, temp = name; *temp != '\0' && i <= MAX_NAME_LEN; temp++, i++)
{
*((s->name) + i) = *temp;
}
s->name[i] = '\0';
}
You can use strncpy to simplify setName:
void setName2(Student *s,const char *name)
{
#include <string.h>
strncpy(s->name, name,MAX_NAME_LEN);
s->name[MAX_NAME_LEN] = '\0';
}