1

Hi all I am really new to C (just started this week), and want to make sure that I am not looking down the wrong rabbit home and hoping to perhaps get pointed to the right rabbit hole.

I create a struct:

#define MAX 64
#define ARRAY_SIZE 2048

struct object {
    int q, c, p;
    char name[MAX]; //Stores string up to 63 characters
    char arr[ARRAY_SIZE][MAX]; // Creates an array of 2048 cells with string of length 63 max
};

int main(){
...
...
int variable = 30;
struct object l[variable]; //This is where the crash happens. But only when either variable is too large (for instance works on 15 just fine, but anything over 20 it crashes), or when Array_SIZE is too larger, for instance works fine with 1024 but 2048 crashes.
...
...
}

The error I get on crash is the following: Process returned -1073741571 (0xC00000FD) in the cmd window. And the following in the debugger in the IDE: Program received signal SIGSEGV, Segmentation fault. [Inferior 1 (process 12120) exited with code 030000000375]

Am I doing something obviously wrong with how I declare an array of structs? Why would large numbers not work but lower numebrs work?

Does the above error indicate I am accessing something out of bounds somewhere? Ive been up and down the code and cant seem to find any reason why larger numbers dont work and lower ones do. My memory footprint doesnt seem to be the issue, just a few megs of memory.

I need help with what to look for (I cant find any instances of accessing anything out of bounds, so I get the feeling Im not chasing the right rabbit and need to look for something else)? Or maybe Im doing something illegal for C without knowing it?

Duxa
  • 966
  • 2
  • 14
  • 27
  • 1
    Maybe it is because of something you do not show. – Gaurav Sehgal Jan 12 '18 at 08:52
  • @GauravSehgal Yeah it may be (this is 300 lines of code and is for a class, so I didnt want to post it all), I was hoping the above (maybe error messages or something) would give an idea to you guys on what may be wrong? – Duxa Jan 12 '18 at 08:53
  • 4
    Each of your `struct object` instances statically allocates 131K of memory (i.e. On the stack). The stack is not that big (compared to the heap). You're running out of memory – Tibrogargan Jan 12 '18 at 08:53
  • 1
    Allocate dynamically... – user2736738 Jan 12 '18 at 08:54
  • @Tibrogargan Oh, good point, so I need to utilize malloc? Any way to confirm this (probably correct) theory? Do debuggers (IDEs) usually have a way to show space on the stack? – Duxa Jan 12 '18 at 08:54
  • what IDE are you using? – user2736738 Jan 12 '18 at 08:56
  • Try to replace `struct object l[variable];` by `static struct object l[variable];` and see if the error goes away. If it goes away it means that there is not enough stack space available. – Jabberwocky Jan 12 '18 at 08:56
  • 2
    Yep. Use dynamic memory allocation instead (`malloc` or friends) – Tibrogargan Jan 12 '18 at 08:56
  • @coderredoc Im new to C, this would mean use malloc right? – Duxa Jan 12 '18 at 08:56
  • @coderredoc Hi Coderredoc, I am using Code:Blocks with GCC – Duxa Jan 12 '18 at 08:57
  • One option is to increase stack size, see [Change stack size for a C++ application in Linux during compilation with GNU compiler](https://stackoverflow.com/q/2275550/45249) – mouviciel Jan 12 '18 at 08:59
  • 3
    BTW `0xC00000FD` is the Windows error code for stack overflow. – Jabberwocky Jan 12 '18 at 08:59
  • @MichaelWalz Wow thanks!!!! That kind of irrefutably proves what Tibrogargan said. THANKS! – Duxa Jan 12 '18 at 09:00
  • 1
    @mouviciel Changing the stack size isn't really scalable, especially when he could just use dynamic allocation and easily avoid the issue – Tibrogargan Jan 12 '18 at 09:00
  • @Duxa.: Yes.... – user2736738 Jan 12 '18 at 09:02
  • @Tibrogargan True. This is why I suggest it as "One option" and leave it as a comment only. – mouviciel Jan 12 '18 at 09:02
  • Thank you guys. Love this community (although admitedly sometimes you guys are a bit rough on newbies like myself, and I guess somewhat deserved, Im an idiot for not googling the windows error code, I guess I assumed it would give me some generic thing I dont understand like most windows codes do... but assuming made an ass out of me :) ) Anyways love this community for being able to respond so quickly and actually help A LOT! Thanks again to all of you. Ill try using malloc (changing stack size is not an option since the code has to be compilable by the instructor of the class on his machine) – Duxa Jan 12 '18 at 09:05
  • Arrays on the stack can escalate pretty quickly, better to learn it now with one very big array than crashing when you write some recursive function with a smaller footprint per recursion step (not that such a thing would have *ever* happened to me :p) – grek40 Jan 12 '18 at 09:08
  • This has been asked hundred times before. Please check out the SO C FAQ, found under the [C tag wiki](https://stackoverflow.com/tags/c/info). – Lundin Jan 12 '18 at 09:22
  • @Lundin.: Have you checked the answer provided here? Just asking. – user2736738 Jan 12 '18 at 09:28
  • @coderredoc Yes. Why someone is getting a crash because of allocating too large an array with automatic storage duration has been answered a hundred times before. – Lundin Jan 12 '18 at 09:30
  • @Lundin.: Both the other 2 answers strangely say "statically allocate" - opposite of dynamic is not static. We can allocate statically and if OP did that there won't be any problem - static allocation is different from automatic amem allocation. And that's why I gave the answer. – user2736738 Jan 12 '18 at 09:35
  • 1
    @coderredoc Any other form than automatic storage duration would be fine. That includes allocated storage and static storage. Fixed-sized arrays are sometimes referred to as statically allocated, which refers to the array size being static, rather than the storage duration. Anyway, if there are incorrect answers posted here, that does not make the question less of a duplicate. There exists a canonical duplicate for this FAQ, which I have given. – Lundin Jan 12 '18 at 09:41
  • @Lundin.: I am not saying about duplicate - Yes your duplicate is right and so is your judgement. And I am just putting that it is wrong way of saying this... *you statically allocate too much memory on the stack.*..and then *you shouldn't allocate statically but dynamically.*.. They said it wrong. This is what is mentioned in the other answers. – user2736738 Jan 12 '18 at 09:43

3 Answers3

3

I think your program crashes because you statically allocate too much memory on the stack. Try using the malloc or calloc function. It dynamically allocates memory on the heap instead e.g. :

struct object *l = malloc(variable*sizeof(struct object));

Don't forget to free it afterwards using the free function.

free(l);

nabil.douss
  • 634
  • 4
  • 10
  • As others suggested it was because I was allocating on the stack and running out of memory. This one line change solved it for me. Thanks! – Duxa Jan 12 '18 at 09:16
2

You have a memory size problem, try to increase the memory size for your program.

And if you want to use big array size and so allocate a lot of memory, you shouldn't allocate statically but dynamically. So you should use malloc

typedef struct object {
  int q, c, p;
  char name[MAX]; //Stores string up to 63 characters
  char arr[ARRAY_SIZE][MAX];
} myObject ;

int variable = 30;
myObject *l = malloc(sizeof(myObject) * variable);

I do not advice you to declare an array of 2048 statically, so you should initiate your struct with a function.

typedef struct object {
  int q, c, p;
  char name[MAX]; //Stores string up to 63 characters
  char *arr[MAX];
} myObject ;

myObject    *createNewObject() {
    myObject *toReturn = malloc(sizeof(myObject) * variable);

    if (toReturn == NULL)
       return NULL;
    toReturn->arr = malloc(sizeof(char) * ARRAY_SIZE);
    return (toReturn);
}

void        freeMyObject(myObject *objectToFree)
{
    if (objectToFree && objectToFree->arr =! NULL)
       free(objectToFree->arr)
    if (objectToFree)
       free(objectToFree)
}

void main()
{
    myObject *myNewObj = createNewObject()

    // You can do some stuff with myNewObj but always verify the pointers
    freeMyObject(myNewObj);
}

You should also debug with valgrind when you works with malloc, so you don't have memory loss or problems.

Hope I helped

Sacha.R
  • 394
  • 2
  • 17
  • Sacha Yes thanks! However why use a function instead of changing the one line as nabil suggested? Also, why are you using typedef for declaring a struct instead of how I did it? Is that a better way? – Duxa Jan 12 '18 at 09:14
  • When you work with structures, malloc and array in structures, you should learn to deconstruct your code into severals function. Suppose that you have to add some dynamically malloc array inside your structures, you just have to modify the creation function. you should REALLY Decompose your code like I did when you work with memory. (and even when you don't ! ) – Sacha.R Jan 12 '18 at 09:23
  • About the typedef, it's just a preference I have to using struct. It's more lisible, more practical to use, and takes less characters. It's a better visibility way. When you code, you should always be lisible and easily comprehensible ! :) – Sacha.R Jan 12 '18 at 09:24
1

Well the problem you had is - you have used automatic memory allocation. Due to constraint of size of automatic storage your program crashed - you asked for more than you should.

So what is the solution?

  1. Static memory allocation:

Solution being

     static struct object l[variable];
  1. Dynamic memory allocation

    struct object *ptr = malloc( sizeof *ptr * variable);
    

The storage of these allocation is different from automatic variables - so free from the size constraint . In this case you have to free the dynamically allocated memory. That's why you will get around the problem you have.


Statically allocate is not a confusion free term. All these types of variable will have different scope - lifetime. Standard never mentions about stack or heap . It is the implementation that follow these to store automatically allocated memory and dynamically allocated memory.

user2736738
  • 30,591
  • 5
  • 42
  • 56