Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Dynamic Structure Array

Status
Not open for further replies.

chigley

Programmer
Sep 30, 2002
104
GB
This is driving me a little crazy

I have a struct

typedef struct{
char url [1000];
char ip [16];
}DnsEntry;

I want to create a dynamic array of these and populate them

like

Code:
dnscache = (DnsEntry*) malloc(sizeof(DnsEntry) * 2);

char *url="[URL unfurl="true"]www.yahoo.com";[/URL]
    char *ip="87.248.113.14";

    memset(dnscache[0].url,0x0,sizeof(dnscache[0].url));
    strcpy(dnscache[0].url,url);

    memset(dnscache[0].ip,0x0,sizeof(dnscache[0].ip));
    strcpy(dnscache[0].ip,ip);
    
    url="[URL unfurl="true"]www.bbc.co.uk";[/URL]
    ip="212.58.253.67";

    dnscache[1] = (struct DnsEntry *)malloc(sizeof(DnsEntry));
    
    memset(dnscache[1].url,0x0,sizeof(dnscache[1].url));
    strcpy(dnscache[1].url,url);

    memset(dnscache[1].ip,0x0,sizeof(dnscache[1].ip));
    strcpy(dnscache[1].ip,ip);

It compiles, but the array is not creating correctly. I have googled this, and not found anything that works for me. What I need to understand it how to

dynamically size the array,
put DnsEntry records into the array
add more DnsEntry records into the array.

Could someone post some code or a link to where I should be looking?

Thanks

Charlie Benger-Stevenson
Hart Hill IT Ltd
 
Almost there
Code:
// Allocate the memory
dnscache = (DnsEntry*) malloc(sizeof(DnsEntry) * 2);

// Assign element 0
char *url="[URL unfurl="true"]www.yahoo.com";[/URL]
    char *ip="87.248.113.14";

    memset(dnscache[0].url,0x0,sizeof(dnscache[0].url));
    strcpy(dnscache[0].url,url);

    memset(dnscache[0].ip,0x0,sizeof(dnscache[0].ip));
    strcpy(dnscache[0].ip,ip);
    
// Assign element 1
    url="[URL unfurl="true"]www.bbc.co.uk";[/URL]
    ip="212.58.253.67";

    // This has already been allocated above
    //dnscache[1] = (struct DnsEntry *)malloc(sizeof(DnsEntry));
    
    memset(dnscache[1].url,0x0,sizeof(dnscache[1].url));
    strcpy(dnscache[1].url,url);

    memset(dnscache[1].ip,0x0,sizeof(dnscache[1].ip));
    strcpy(dnscache[1].ip,ip);
 
Mmmmm it compiles but crashes when I run it.

The struct array is declared as
Code:
typedef struct{
       char url [1000];
       char ip [16];
}DnsEntry;

DnsEntry **dnscache = NULL;

and the function that is causing the crash is as below (albeit now simplified to just load the first element in for clarity and ease of testing

Code:
int loadTestCacheData()
{
    
    dnscache = malloc(sizeof(DnsEntry) * 2);
    
    //Currently loading dummy data into the cache for testing purposes
    char url="[URL unfurl="true"]www.yahoo.com";[/URL]
    char ip="87.248.113.14";
    
    memset(dnscache[0]->url,0x0,sizeof(dnscache[0]->url));
    strcpy(dnscache[0]->url,url);

    return 0;
}

Charlie Benger-Stevenson
Hart Hill IT Ltd
 
I thought you'd declared it as

DnsEntry *dnscache = NULL;

If you declare something as

xxx *fred;

then you allocate as

fred = (xxx*) malloc (...);

If you declare it as

xxx **derf;

then you allocate as

derf = (xxx**) malloc (...);
*derf = (xxx*) malloc (...);

Note that you will need 2 mallocs in this case.
 
I have declared it as both. Believe me I am trying everything I can, not necessarily knowing what I am doing, which is why I could really use some example code that works and a bit of an explanation.

I have decided to try and write a function to add items to the array, that is reallocate memory to the array, and then add the nth structure to it. I have

Code:
void addDnsEntry (DnsEntry item)
{
     dnscache = (DnsEntry*)realloc(dnscache, (lNumCacheItems + 1) * (sizeof(DnsEntry)));
     dnscache[lNumCacheItems] = item;
     lNumCacheItems++;
     return;
}

where the declarations section looks like

Code:
typedef struct{
       char *url;
       char *ip;
}DnsEntry;

DnsEntry *dnscache = NULL;
long lNumCacheItems=0;

then in my test harness code I call the function

Code:
char *url="[URL unfurl="true"]www.yahoo.com";[/URL]
    char *ip="87.248.113.14";
 
    DnsEntry firstEntry;
    DnsEntry secondEntry;
    
    firstEntry.url = malloc(strlen(url) * sizeof(char));
	firstEntry.url = strdup(url);
    firstEntry.ip = malloc(strlen(ip) * sizeof(char));
	firstEntry.ip = strdup(ip);
    
    addDnsEntry(firstEntry);
    
    char *url2="[URL unfurl="true"]www.bbc.co.uk";[/URL]
    char *ip2="212.58.253.67";
    
    secondEntry.url = malloc(strlen(url2) * sizeof(char));
	secondEntry.url = strdup(url2);
    secondEntry.ip = malloc(strlen(ip2) * sizeof(char));
	secondEntry.ip = strdup(ip2);

    addDnsEntry(secondEntry);

In the debugger, I can put a watch on the 'item' argument and it is populated correctly. I can also put a watch on the zeroth and first element of the dnscache array, and see the url and ip members of each member, but the contents are garbage eg 8A instead of
Somewhere the memory is getting screwed and I can't see how

Thanks in advance

Charlie Benger-Stevenson
Hart Hill IT Ltd
 
strdup is the same as malloc + strcpy so you actually have a leak where you are doing a malloc followed by a strdup.

If something is assigned a NULL value, you cannot realloc it. That is probably where your corruption is coming from.

Also, structure copys on the stack are not very efficient.
Code:
void addDnsEntry (DnsEntry item)
{
     if (lNumChacheItems == 0)
        dnscache = (DnsEntry*) malloc (sizeof(DnsEntry));
     else
        dnscache = (DnsEntry*)realloc(dnscache, (lNumCacheItems + 1) * (sizeof(DnsEntry)));
     
     dnscache[lNumCacheItems] = item;
     lNumCacheItems++;
     return;
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top