The biggest problem here is that this is C not C++, however, let's consider a C solution:
There are a few problems:
struct Response {
Record *records[];
};
Don't forget to give a dimension for your array:
Record *records[4];
Next:
struct Record {
char *name;
};
This just declares a pointer called name, there is no memory allocated for name to point at. You will need to allocate memory for name in the future, or make it a static array here instead of a pointer.
record->name = (char*)x;
Now name is pointing at a static array x. This will happen every time through the loop, so all the record->name instances will be pointing at the same array. That's why they're all printing the same value :-)
You need to copy the string in x to record->name, which you can't do, because there is no storage associated with record->name.
The 2 ways out are:
struct Record {
char name[20]; // static array
};
...
char x[20] = {0}; // initialise so we're sure of a terminating null
strcpy(record->name, x);
Or
struct Record {
char *name;
};
...
record->name = new char[20];
strcpy(record->name, x);
Finally,
//Not sure if I have to delete.
delete record;
No, you mustn't delete here, as those records will be used afterwards. If you must delete, set up something like your initialisation loop, but just before the end of main(), only this time you'll be destroying.
Of course, srictly speaking, since this is C, you shouldn't be using new and delete. malloc() and free() family of calls are better suited to C style.
The main advantage of new and delete over malloc() and free(), is that call the constructors and destructors of allocated objects at the right time, but you haven't used either of those features.
This would be a lot easier, shorter and safer in C++. Must you do it in C or would you consider C++?
#include <iostream>
#include <cstring>
struct Record {
char *name;
};
struct Response {
Record *records[4];
};
int main()
{
Response *response = new Response;
for(int i=0; i<4; i++) {
Record *record= new Record();
char x[20];sprintf(x, "%d", i);
record->name = new char[20];
strcpy(record->name, x);
response->records[i] = record;
std::cout << "Inserting: " << x << "\n";
//Not sure if I have to delete.
//delete record;
}
for(int i=0; i<4; i++) {
std::cout << "Fetching: " << response->records[i]->name << "\n";
}
// the program is about to exit and the resources will be freed by the system, so this is not strictly necessary
for(int i=0; i<4; i++) {
delete [] response->records[i]->name;
delete response->records[i];
}
delete response;
}
EDIT: Here's one possible solution that's more C++ friendly, no raw pointers, all memory allocation is handled by the standard library in string and vector.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct Record {
Record(string record_name) : name (record_name) {}
string name;
};
struct Response {
vector<Record> records;
};
int main()
{
Response response;
for(int i=0; i<4; i++) {
response.records.push_back(Record(to_string(i)));
std::cout << "Inserting: " << i << "\n";
}
for (auto r : response.records) {
cout << "Fetching: " << r.name << "\n";
}
}