0

So I'm trying to declare a struct of size 19,000, however when I compile this I get Seg fault, core dumped. I think I have to use malloc but I can't figure out whats the best syntax to use considering I'm not using pointers!!

Struct people{
    char name[100]
    char secondname[100]
   }


int main(){
    struct people p1[19000]
}

Above is the code corresponding to my problem

Any Help would be greatly appreciated

  • Either increase the stack limit on your platform (i.e. `ulimit -s unlimited`) or use `struct people *p1 = malloc(19000*sizeof *p1);` to allocate on the heap. – Ctx Oct 21 '18 at 21:11
  • 1
    And, fyi, the terms *"I think I have to use malloc"* and *"I'm not using pointers!!"* are wishful thinking to do in tandem. If you do the former, you had better be doing the latter. – WhozCraig Oct 21 '18 at 21:17
  • 2
    To underline what @WhozCraig says, when you use `[ ]` notation to access an array you *are* using pointers, you just don't realise it (yet). – cdarke Oct 21 '18 at 21:22
  • `malloc` returns a pointer, so one can't avoid them; something like `#include ` ... `struct people *p1 = malloc(sizeof *p1 * 19000); if(!p1) perror("people"), exit(EXIT_FAILURE);`. – Neil Oct 21 '18 at 21:24
  • _" when I compile this I get Seg fault,"_ - I really doubt that. When you _run_ the compiled code, it will fault, but compilation should not be a problem. – Clifford Oct 21 '18 at 21:26
  • @cdarke technically, you are not using pointers when indexing an array. – Ctx Oct 21 '18 at 21:28
  • 1
    @ctx: Technically, yes you are. The array decays to a pointer prior to adding the index. (`E1[E2]` is identical to `(*((E1)+(E2)))` -- 6.5.2.1/2. Also see 6.5.2.1/1, constraints.) – rici Oct 21 '18 at 23:19
  • @rici Just because it is identical (meaning it evaluates to the same value) doesn't mean, that you are using pointers. None of the objects in p1[100] for example is a pointer, so you are obviously _not_ using pointers. – Ctx Oct 22 '18 at 07:41
  • @ctx: I guess that depends on how you define "using" . 6.5.2.1 says that in an array subscripting expression, «One of the expressions shall have type "**pointer** to complete object *type*", the other expression shall have integer type». `p1[100]` satisfies that constraint because `p1` is previously decayed to a pointer. To me that seems like it's using a pointer -- the pointer the array is converted to automatically. – rici Oct 22 '18 at 14:22
  • And, by the way, in this case at least, "identical" means "identical", as in "textually substituted with", which is a stronger equivalence than "evaluates to the same value". – rici Oct 22 '18 at 14:59

2 Answers2

1

Your struct array requires about 3.8Mb of stack space, while on most modern Desktop platforms, the typical default process or thread stack is perhaps a couple of Mb.

You can either dynamically or statically allocate the memory. Static allocation if simplest and appropriate is the lifetime of the array is the duration of program execution, and the required size is known a priori.

int main()
{
    static struct people p1[19000] ;
}

Dynamic allocation is a possible solution, but since malloc() returns a pointer to the allocated memory, you are necessarily using pointers; but array access notation can be used, so your exposure ot pointers will be minimal:

int main()
{
    struct people* p1 = malloc(sizeof(struct people) *19000 ) ;

    ...

    // Access to elements of the dynamically allocated array
    // is identical to that of the statically allocated array.
    printf( "%s", p1[0].name ) ;
}

An advantage of dynamic allocation is that you can avoid allocating an arbitrarily large space, and create records on demand, storing pointers in a dynamically resizing array (using realloc() for example), or some suitable container data structure such as a linked list. But perhaps that is too advanced for where you are at at the moment.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • does the "static" keyword automagically create more memory on the stack? – anneb Oct 21 '18 at 21:36
  • How do you calculate the 181Mb? I think, it's "only" 19000*200 = 3800000 (3.8MB) – Ctx Oct 21 '18 at 21:37
  • @anneb : No it allocates it in separate memory - it is permanent and separate from the stack, and is instantiated and initialised only once - even if it has local scope. To increase the stack size, you will need to consult your compiler and or operating system documentation. For example: https://stackoverflow.com/questions/2275550/change-stack-size-for-a-c-application-in-linux-during-compilation-with-gnu-com – Clifford Oct 21 '18 at 21:50
  • @Ctx : I calculate 181Mb by incompetence! Fixed. – Clifford Oct 21 '18 at 21:51
0

struct people p1[19000] tries to create 19000 structs of 100+100 bytes in automatic stack memory. Normal stack memory is not large enough and you get a stack overflow or some other error.

In C, there is much more heap memory available, but the programmer has to do the heap memory management

To allocate the array in heap memory, you can use for instance:

int main() {
   struct people *p1 = malloc(19000 * sizeof(struct people));
   // you can now access p1 using array brackets as follows:
   // strcpy(p1[0].name, "name");
   // strcpy(p1[0].secondname, "secondname");
   // printf("name: %s, secondname: %s\n", p1[0].name, p1[0].secondname);

}
anneb
  • 5,510
  • 2
  • 26
  • 26