Is it incorrect (or problematic) to create a string array struct?

Asked

Viewed 219 times

5

I’m not sure what’s the ideal way to create a structure (struct) that contains a array of string, in case I have a structure like this:

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    char nome[81];
    char atores[81][100];
} Filme;

int main()
{
    Filme x[1000];

    return 0;
}

By running this simply the program ends (crash), then I debugged with GDB to try to understand what could be the cause and got only the message:

Program Received Signal SIGSEGV, Segmentation fault.

I assume it’s my mistake to be using it in a way that memory exceeds or maybe I can’t manage, because by executing this Filme x[1000] many structures are created, when I create something smaller, for example Filme x[20], the problem does not occur.

So I thought I’d create a framework for the atores separate and reference/relate them through an ID (which in this case would be the index item), something like:

typedef struct
{
    char nome[81];
} Filme;

typedef struct
{
    int filmeref;
    char ator[81];
} Atores;

this would be "correct"?

1 answer

7


It’s that old thing, it all depends. Where are you going to use it? What’s the point? How are you going to manipulate it?

Sizes

An instance of the structure Filme will always be more than 8KB in size, no matter if you need much less, or if you need more, have nowhere to put. Is this what you want? Unlikely.

Think about a database. You want to use char or varchar? In that case used char. Moreover, if a column can have N elements it prefers that this be put in: another table; normalizing or with a variable format; like XML, JSON, or something similar even one itself? Or something fixed? That’s what you did.

But there are cases that might be interesting to do.

You also have to wonder if you really want to create a array with 1000 elements. There are more than 8MB occupied, and if you want more than 1000 films, there is no way. Of course you can create a bigger one and copy everything, which is not so trivial.

If you want to manipulate something like this in a real application, it can be very complicated or waste resources. This is for something very simple, that you have control or exercise.

Allocation

One of the things I’d probably do is have a array of pointers for elements of Filme, probably allocated in the heap. Probably the very array should be allocated in the heap with malloc() instead of using the stack. There’s a lot of links in another question. But you need to get a good look at what the best allocation strategy.

It is likely that in this case there would be benefits in using indirect in everything. But it depends on factors that cannot be defined only by this description. You probably have pointer.

Crash

To solve the crash can generate an executable with a larger stack to fit everything, usually the default stack is 1MB. But it is still a solution probably bad, the stack should not be abused so in most cases.

If you don’t change the general architecture then the proposed solution of separating the structures won’t help much, although it is already a gain for being normalized, now there will be less waste and you can attend movies with more than 100 actors. It will take longer to burst, but still have problems if you continue allocating in stack.

To stack is for very small things, or for a quick test, or even when you have a lot of control over its use and you need it too much. I’ve done things where I’ve abused the stack and set a 4GB :), but this is not common.

Modeling

Still there is a conceptual error of modeling since the actor is linked to the film, so there will be dozens of Jerry Lewis registered, when there is only 1 Jerry Lewis. It’s the problem that I always talk about object orientation where people follow book recipes and model everything wrong. It would be better to have a list of actors identifiers in the film and only one instance of that actor.

But then we return to the problem of the lack of normalization (second, the first would be being respected). So the solution would be to have a separate list of actors (only the Ids that point to the actor’s chart itself). That list could be one array, or a linked list with the first element already placed in the structure of the film, or a tree if it needs certain characteristics, or a scattering table, or another structure that better meets demand, each with its advantages and disadvantages. If you choose a dynamic list based on array will have to devise growth strategies.

There’s a way to maintain a single structure for all the actors in the movies, that is, instead of having a list per cast, you have everyone together, then you have to have a key and value, with the movie ID and the actor ID, that’s a list of strings. In traditional relational databases is the only way to make it sound.

Unless you get a ready-made library you’ll have to do everything by hand, including manage memory.

Anyway it is clear to a real case that the stack it is impossible for all this.

An idea:

typedef struct {
    const char *nome;
    //outros campos
} Filme;

typedef struct {
    const char *nome;
    //outros campos
} Ator;

Each nome, of Filme or of Ator will stay in the heap with malloc() (see the difference).

Each Filme or each Ator would be allocated individually from the heap, always with malloc(), of course, unless you need a more personalized strategy, which is rare and well advanced. People confuse this whole array physical and array formed by referenced elements.

The list Filmes and the list Elencos (this is a strategy, which connects well with relational DB) also would heap, probably as a array, but not necessarily. In the case of Filmes would have only pointers for each Filme. And Elencos would vary, but it could be such a structure:

typedef struct {
    Filme *filme;
    Ator *ator;
} AmarracaoFilmeAtor;

I put in the Github for future reference.

If you choose a array per movie there could use the pointer to the direct actor on array (in the heap), which may be a gain, but complicates some management, then one of the fields of Filme would be a pointer to the list Elenco of this film. Conceptually I like it better. Even one of the reasons I do experiments with database development is precisely to have this kind of freedom (Nosql would be an obvious solution if it did not have certain costs that I do not want to pay).

Completion

None of this seems very accurate.

Might also be of interest:

  • Wow, sensational, even more so when you took the issue to the modeling side, which is actually my main problem. I will read everything calmly. I really appreciate.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.