简体   繁体   中英

Using a pointer to point to many struct and access the structures data members

typedef struct Halls Hall;

struct Halls{
    char *hallName;
    int **seats;
};

void fillInHall(Hall *hall){
/* This one is just an example but, it'll be filled with different data and names*/
int i;
for(i = 0; i < 3; i++){
    hall[i].hallName = "Main-Hall";
    /*Pin*/
    }
}

void main(){
    Hall *hall = malloc(3 * sizeof(Hall));
    fillInHalls(hall);
}

What code should be written in /*Pin*/ to store the new data in the next memory address to access their data as hall[i].hallName not being overwritten?
I tried hall++; But, it seems it doesn't work. And how can I do realloc() if the halls created was more than 3 ?
Thanks ....

Java and other languages allow you to copy strings by doing something like:

string a = "This string";

However, in C, this means you are copying the ADDRESS of the string, not the characters themselves.

char * a = "This string";

In the example above, the string is stored somewhere in memory and occupies exactly 12 bytes (assuming single-byte characters, 11 characters + the terminating null character). The assignment above puts that string's address in A. If you then do something like:

a = "Some other, longer string";

a then points to that other string (different place in memory).

hall[i].hallName = "Main-Hall" tells the program to get the address of a string containing "Main-Hall" and store it in hall[i].hallName. I believe this means you are making all instances of Halls point to the same string in memory. This would mean that they would share the same memory, which in turn means that if you change one, you change all of them.

In Halls, you probably want to define the hallname to be a char array, ex:

#define HALL_NAME_MAX_SIZE 81 // Name is 80 characters max + 1 for null termination
struct Halls {
    char hallName[HALL_NAME_MAX_SIZE]; 
}

This allows each hall to have its own storage space for its name. Then, in your for loop, copy the "Main-Hall" into that storage using snprintf:

snprintf(halls[i].hallName, HALL_NAME_MAX_SIZE, "Main-Hall");

(You could also use strcpy, strncpy, but snprintf handles null-termination a bit more safely)

Alternatively, if you want to use dynamically-sized strings, you will need the original char * in Hall, but you will need to allocate memory first in the loop:

void fillInHall(Hall *hall){

    int i;
    for(i = 0; i < 3; i++){
        halls[i].hallName = (char *) malloc(80); // Can be any number you want
        // You could use an existing string too
        // halls[i].hallName = (char *) malloc(strlen("Main-Hall") + 1); 
        snprintf(halls[i].hallName, HALL_NAME_MAX_SIZE, "Main-Hall");
    }
}

Don't forget free on all of the hallNames when you don't need them anymore!

void freeHall(Hall *hall){
    int i;
    for(i = 0; i < 3; i++){
        free(hall[i].hallName);
    }
}

Simple example:

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

typedef struct Halls Hall;

struct Halls{
    char *hallName;
};

void fillInHalls(Hall *hall){
char *names[] = {"A example", "B example", "C example"};
int i;
    for(i = 0; i < 3; i++)
        hall[i].hallName = names[i];
}

int main(){
int i;
    Hall *hall = malloc(3 * sizeof(Hall));
    fillInHalls(hall);
    for(i = 0; i < 3; i++)
        printf("%s\n", hall[i].hallName);
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM