Calloc of a struct

Hello gentlemen (and ladies). I am building a database for a project and I came across this calloc function that seem to be appropriated to what I want if I understand correctly its usage.

I'm attempting to create a database like this:

[An array of 2000]
[Each block contain if their data and how many (0,1,2,3,4,etc)]
[And a pointer to the data structure]

1
2
3
4
5
6
struct BD_case{
  int  nb_sentence;               //nb of sentences
  sentences  *address_sentence;   //pointer to the next sentence
};

BD_case T_Base_Data[2000]={0};


1
2
3
4
5
typedef struct sentences{
  char *sentences_FR;     //will contain a string 
  char *sentences_AN;	  //will contain a string
  sentences *next;        //will contain the address to the next data block
};                        //(its a pointer) 


My goal is to read from a file 2 string and put them in a memory space. To avoid wasting memory space I though I could use calloc as a custom memory allocation. I would only need to asked for a certain amount of space to hold the strings, the minimum required.

Reading on calloc I find it somewhat confusing on how to access those addresses in a struct. Also lets say string 1 and string 2 are not the same size, do you declare the total amount of space they use? or declare 2 different thing. That the part I get lost and I was wondering how it could be done.
if this is a C++ project, start by using

vector<pair<string, string>> as BD_case

or perhaps

1
2
3
4
5
6
struct sentences {
    string sentences_FR;
    string sentences_AN;
};
typedef vector<sentences> BD_case;
vector<BD_case> T_Base_Data ;


Last edited on
I'm actually using the c with some libraries. I wish I could use C++ more direct method :(
Your BD_case and sentences structs are always going to be the same size - they contain integers and pointers only.

So your allocation for each set of 'num' sentence structs would be calloc (num, sizeof(sentences));

However, if you're using this method of allocation, your sentence structs are going to be in contiguous memory, so the *next pointer is redundant as you can use pointer arithmetic to traverse the resultant array of structs.

Additionally, seeing as you're using pointers, you now have the added overhead of allocating and freeing each string that the sentences_FR and sentences_AN reference. You can use strdup() to duplicate a string - it will allocate the memory and copy the string into it. Don't forget to free() the resulting memory once you're done with it.

Cheers,
Jim
I`m a bit confuse. I know the BD_case wont be anything significant as it will only hold an integer with the number of data block attach to it and a pointer to the first datablock (if there one).

My whole problem come when I declare that contiguous memory and then accessing it.

Lets say string1 = "yo"; and string2 = "blablabla"

As in your example NUM is the amount of item to be allocated. So with yo and blablabla the amount to allocate would be 11 characters. Would you just say tempptr = calloc (num /*that would be 11*/, sizeof(sentences)); where tempptr receive the pointer to the address of the memory block and would you use tempptr.string1="yo"; to put said string inside the data block?

I know you can use the pointers directly to point toward the beginning of the string inside the memory that has been allocated but it would be simpler if I just tell a function : In BD_case 33, how much data block is there? answer 3! What are all the first strings inside the data block (in my case FR), etc.

Thanks for the help so far.

P.s
tempptr would be declared as a sentences tempptr; in this case.
Last edited on
You're getting mixed up with pointers to char and arrays.

In the case of your sentences struct, it doesn't contain two strings, it contains two pointers to strings; the strings themselves will be elsewhere, and you have to allocate their memory as well.

Ignoring calloc for a second, let's just create an instance of a sentences struct:

1
2
3
4
5
6
7
typedef struct sentences{
  char *sentences_FR;
  char *sentences_AN;
  sentences *next;
};

sentences aSentence;


The size of this instance will be sizeof(char*) + sizeof(char*) + sizeof(sentences*), the size of three pointers. On 32 bit architectures, this will equate to 4 + 4 + 4, so each sentences struct is 12 bytes long.

Now, at this point, both the sentences_FR and sentences_AN pointers are uninitialised and will be pointing to some random piece of memory, but more importantly they don't contain strings. We have to create the strings ourselves and set the sentences_FR and AN pointers to point to them.

We can do this using strcpy, strdup or other str functions. For example, strdup will duplicate a string, allocating the required memory for us ...

1
2
3
4
char string1[] = "yo";
char string2[] = "blablabla";
aSentence.sentences_FR = strdup(string1);
aSentence.sentences_AN = strdup(string2);


We now have new copies of string1 and string2, pointed at by aSentence.sentences_FR and aSentence.sentences_AN.

Using our new-found understanding, we can now dynamically allocate a whole array of 42 (for example) sentences using:

sentences* tempptr = calloc(42, sizeof(sentences));

We now have 42 uninitialised sentences which we have to populate in the same way as our previous example.

The tempptr pointer will be pointing at the first sentence, so we can say:

1
2
3
sentences* entryPtr = tempptr; // entryPtr now points to 1st element of array
entryPtr->sentences_FR = strdup(aString);
entryPtr->sentences_AN = strdup(anotherString);


To move to the next element of the array, we just use pointer arithmetic: entryPtr++;. The compiler knows how big a sentences struct is, so it knows to shift the pointer by that many bytes when you increment it. If you want to access the 4th entry directly, for example, you'd say entryPtr = tempptr + 3;

Cheers
Jim
Topic archived. No new replies allowed.