0
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 ....

7
  • 3
    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 overwrite them? Can you rephrase this. I don't understand at all what you mean here. Commented Oct 28, 2016 at 14:32
  • What do you mean with next memory address?? Commented Oct 28, 2016 at 14:34
  • I mean after storing different names of the halls like: hall[o].hallName = "A"; and hall[1].hallName = "B"; while assigning the data how can I avoid overwriting the old data stored before? because when I try to access hall[o].hallName = "A"; I get B not A ... Commented Oct 28, 2016 at 14:38
  • I can say, how can I use index mark to access the structures I am pointing to by *hall ? Commented Oct 28, 2016 at 14:39
  • @HazemAlabiad - We cross posted on your suggested edit to my answer. It's fixed now. I was confused by the cross posting. Thanks for the edit suggestion. Commented Oct 28, 2016 at 15:35

2 Answers 2

1

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);
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

How about storing int values?
And Can I access different structures using the pointer *hall by index?
let's say you have a hallNumber in Halls: struct Halls { int hallNumber; }. This creates the storage for one int in Halls. Thus halls[0].hallNumber = 1 copies '1' into the storage inside halls[0]. This does what you would expect it to.
How can I realloc() memory for bigger size? so that, it doesn't overwrite the old data?
In that case, instead of using statically allocated sizes like in my example, you will need to first allocate the memory, then copy into it. Then you can reallocate it later before copying a new string to it. I'll update my example.
0

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;
}

8 Comments

This works, provided nobody tries to edit the hallName later. if someone tried strcpy(hall[0].hallName, "Some long string that extends beyond the initial bounds"), then the string would overrun the storage reserved for "A example" and could corrupt other variables next to it. If, for example, the storage for "B example" is right next to "A example", the extraneous characters would bleed over into it.
Thus, if you are using this technique, you should be working with char const * for hallName and char const * const for names[]. This prevents functions from being allowed to modify the strings.
@BareMetalCoder - true, this was just a simple example. It's unknown if the strings in the hall structures are to be literals (const char *) or if they are to be modifiable strings. The point of this simple example was to show one assignment per loop in fillInHalls(). In the case of this simple example, since the strings are literals, trying to modify them would probably result in segmentation (write to protected memory) fault.
Understood, I just wanted to warn against editing them. I'm pretty sure you can technically go ahead and write to them as long as you make sure you don't corrupt them. Hence the suggestion to make them char const * const -- the compiler will prevent you from any such shenanigans.
@BareMetalCoder - In the case of Visual Studio, literals are placed in read only memory region, so a fault occurs if an attempt is made to modify a literal. I don't know if other compilers do the same.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.