1

I have a pointer array named ipN_details which has type ip_details:

typedef struct
{
   char name[64];
   char ip[16]; 
   char Flags; 
   char mac[17] ; 

} ip_details;

after calling function get_ip_details when I print elements of ipN_details it contains wrong value for element of mac whenever this array contains more than one member. (all other elements have right values that is expected.) For example, when this array has two member value of mac in the first member is concatenated with some of the last characters of name of second member.

first member: name=mina ip=9.9.9.9 Flags=a mac=3f:fd:df:fdakh

second member: name=simakh ip=9.9.9.1 Flags=ab mac=3f:gv:hj:fd

I have tried to debug this code using gdbafter memcpy line , I printed elemnt of mac and it contains right value,I have no idea why it contains wrong value when I print it using cout (I call cout after calling this function get_ip_details). I also printed contents of ipN_details array after memcpy line using gdb. They were also right, thus I think this problem does not relate to function extract_ip.

int get_ip_details(ip_details **ipN_details, int *ip_details_len)
 {
     int_details *int_details_list=0;
     int int_details_list_len = 0;
     int ret = 
     get_int_details(&int_details_list,&int_details_list_len,"eth");
     if(ret == 0)
     {
         int k = 0;
         for(int i=0; i < int_details_list_len; i++)
         {
            ip_details * ipN_details=0;
            int ipN_details_len=0;
            int int_index = int_details_list[i].index;
            extract_ip(int_index, 
            &ipN_details,&ipN_details_len);   // here I read ipN_details_len number of members into ipN_details array using this function 

/*
 * I wanna add members one by one to array ip_details(using for loop with j), 
 * thus I increase allocated 
 * memory of this array using realloc function and then memcpy the members from 
 * ipN_details function to ip_details, one by one
 */


            if (ipN_details_len != 0)
            {
                *ip_details_len += ipN_details_len;
                *ip_details = (ip_details *)realloc(*ip_details,
                (*ip_details_len) *  sizeof(ip_details)); 


                for(int j=0; j < ipN_details_len; j++)
                {
                    memcpy(&((*ip_details)[k]), &
                    (ipN_details[j]),sizeof(ip_details));
                    k++;
                }
            }
            free(ipN_details);

          }
          free(int_details_list);
      }
}

I call this function like this:

ip_details* ips_details=0;
int ips_details_len;
get_ip_details(&ips_details, &ips_details_len);
for(int i=0; i < ips_details_len; i++){
    cout << string(ips_details[i].name) << "-"<< 
    string(ips_details[i].ip_address) << "-"  << 
    string(ips_details[i].mac_address) << "-" << 
    ips_details[i].Flags << endl;

}
Peggy
  • 639
  • 9
  • 28
  • Can you add the code where you call this function, add the `cout` line that prints the wrong value, fix your indentation please, and maybe add some comments? – Brendan Goggin Apr 14 '17 at 18:17
  • @ThingyWotsit I think now it is more readble, sorry. – Peggy Apr 14 '17 at 18:49
  • @Mjina thanks! Some people think it's nitpicking/pedantry, but when there are so many questions, the skilled and experienced SO users that answer questions in free time need as much help as they can get from posters:) – ThingyWotsit Apr 14 '17 at 19:00
  • @Brendan Goggin: I have added some comments. – Peggy Apr 14 '17 at 19:13
  • In `get_ip_details`, you're using a variable called `ip_details` (elsewhere you have `ipN_details` and `ips_details`, but I'm not referring to those), but I don't see where this variable is declared. Is it some global variable that you haven't included? This is the variable that you're realloc'ing. – Dolda2000 Apr 14 '17 at 19:37
  • If you are programming in C++ (and you are, otherwise lines like `cout << string(...` make no sense), why are you managing memory with `realloc` and `free` (not to mention `typedef struct` or the char arrays...)? Aren't you allowed to use standard containers? – Bob__ Apr 14 '17 at 19:41
  • @Bob__, yes you're correct. The "why" doesn't make sense. @Dolda2000, `ip_details` is a type, not a variable. He has the `typedef` at the top of his post. @Mjina, you're missing some crucial information here. Please include the function definitions for `get_int_details` and `extract_ip`, as well as a test case please. – Brendan Goggin Apr 14 '17 at 22:04

1 Answers1

0

I can't get this code to compile because you are missing int_details, get_int_details, and extract_ip. Can you please include those definitions (or replace them with hard-coded values instead of function calls) so I can get it to compile and recreate/fix the problem?

My suspicion is you aren't allocating enough space for you ip_details pointer, so you end up writing beyond your allocated space, and then the second member you mention is overwriting what you wrote in your first member because the memory in which the first member resides was not properly reserved.

A quick observation, you have a 17-char array reserved for mac, and then you try to print it as a string that is only 14 characters long. I'm assuming you don't null terminate the string like you are supposed to before reading it with cout ... string(...). The string function is going to read until it finds the null-terminator, or reads 17 chars, whichever comes first. That's why it reads farther than it should, so you get three undefined characters at the end of that string when you print it. The reason why those three are akh would take a bit more logic/information, but the thing is it doesn't matter what they are, it is undefined territory and a null terminator should end the string before that.

Community
  • 1
  • 1
Brendan Goggin
  • 2,061
  • 14
  • 14