How to dynamically allocate and free memory for the below structure

How do i properly allocate and free memory for structure test in c++

struct test1
{
int a;
long b;
.....
}
struct test
{
test1 testHdr;
char testData[];
};

I tried the below method but program crashes on delete object whenever there is data in testData.

test *msg = new test;

i know that i need to allocate memory for the char array testData also but want to know the proper way of doing it.
Last edited on
program crashes on delete object whenever there is data in testData.

Q. How many elements does the array test::testData have?
A. Why doesn't your compiler at least warn that you have not set it?
Note that zero-sized arrays are not ISO C++ -- they're an extension supported by some compilers. From C++ Shell (with -Wpedantic)

13:17: warning: ISO C++ forbids zero-size array 'testData' [-Wpedantic]


If you are you are going to use them, it's up to you to ensure that you provide the required space.

Andy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <cstring>
using namespace std;

struct TestHdr
{
    int  id;
    long dataSize;
};

struct Test
{
    TestHdr hdr;
    char data[];
};

int main()
{
    const char *msg = "Hello, world!";
    
    size_t dataSize = strlen(msg) + 1;
    
    char *storage = new char[sizeof(Test) + dataSize]{};
    
    Test* test = reinterpret_cast<Test*>(storage);
    test->hdr.id = 123;
    test->hdr.dataSize = dataSize;
    strncpy(test->data, msg, dataSize);
    
    cout << test->hdr.id       << endl;
    cout << test->hdr.dataSize << endl;
    cout << test->data         << endl;    
    
    delete [] storage;
    
    return 0;
}


OR

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

struct TestHdr
{
    int  id;
    long dataSize;
};

struct Test
{
    TestHdr hdr;
    char testData[];
};

int main()
{
    const char *msg = "Hello, world!";
    
    size_t dataSize = strlen(msg) + 1;
    
    vector<char> storage(sizeof(Test) + dataSize);
    
    Test* test = reinterpret_cast<Test*>(&storage[0]);
    test->hdr.id = 123;
    test->hdr.dataSize = dataSize;
    strncpy(test->testData, msg, dataSize);
    
    cout << test->hdr.id       << endl;
    cout << test->hdr.dataSize << endl;
    cout << test->testData     << endl;    
    
    return 0;
}
Last edited on
typically, dynamic memory is avoided in favor of c++ containers.
if you feel you must use it, the class/struct pattern is typically to allocate the memory in the constructor, destroy it in the destructor, and in case you need it, reallocation / modification of the memory is done in some other member function (eg resize). When you run into this you will also find you need to hit the rules of 3/5 to provide an assignment operator (so you don't copy the POINTER but instead make a copy of the DATA into the new copy) and various other issues associated with those rules. If you just use the container as noted, you can clear up all these things, you no longer need explicit ctor/dtor/assignment/etc stuff as it will all just work (barring other complexities). For both containers and pointers, you have to serialize the data yourself if you need to write the object to a file/network/etc.

similarly, for allocation of the object itself, you are better off with a container than a pointer.
but if you need to do that, it is simply this pattern:
objectype * po = new objectype[size];
po[0] = something; //use it
delete[] po; //cleanup.

I can't advise enough to say:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct Test
{
    TestHdr hdr;
    string data;
};

Test * tp = new Test[10];
 tp[0].data = "hello world";
cout << tp[0].data;
delete[] tp;

//same thing without the mess:
vector<test> tp(10);
tp[0].data = "hello world";
cout << tp[0];


and if you need to make pointers everywhere, eg char* data inside, it gets a lot messier in a hurry.
Last edited on
You can give the class it's own overloaded new / delete.
https://www.geeksforgeeks.org/overloading-new-delete-operator-c/

And yes, structs are the same as classes in C++, except for the default member visibility rule of 'struct is public, class is private'.
Topic archived. No new replies allowed.