2

I have an array uint8_t arr[512] and I need to store a string, IP address and a 32digit number in this array. So I thought of defining another array of strings as below.

uint8_t *ch[] = {
     "abcd",
     "1.1.1.1",
     "123456782341223344445"
};

Then do a memcpy into the arr[512]. Is this OK? I think I may not be able to retrieve the IP address from the arr. Any other ideas please. Thanks for your time.

MyPasswordIsLasercats
  • 1,610
  • 15
  • 24
foo_l
  • 591
  • 2
  • 10
  • 28
  • 1
    **No** , look [Difference between `char* str[]` and char `str[][]` and how both stores in memory?](http://stackoverflow.com/questions/17564608/what-does-the-array-name-mean-in-case-of-array-of-char-pointers/17661444#17661444) to know how `*ch[]` stored in memory, memcopy need `source` in continues memory whereas its **not**. – Grijesh Chauhan Jul 22 '13 at 10:52
  • Unrelated: why `uint8_t*` instead of `char*`? – Nikos C. Jul 22 '13 at 10:54
  • 1
    Why not a `struct` that contains a string, a 32Bit-Integer for the IP-adress and a second string for the 32-digit number? – MyPasswordIsLasercats Jul 22 '13 at 10:55
  • @MyPasswordIsLasercats do you mean a `struct` instead of `arr[512]` or `ch[]` ? can you please elaborate. – foo_l Jul 22 '13 at 11:07
  • @foo_l, can *you* elaborate? It's not at all clear what you begin with and what you want to achieve. – StoryTeller - Unslander Monica Jul 22 '13 at 11:13
  • @StoryTeller OK!.. I just want to store strings and others into the arr[512]. So when I try to retrieve them `a[0]` must be `a` `a[1] = b a[2] = c a[3]=1 a[4]=1 a[5]=1 a[6]=1 a[7]=1`and so on.. Am I clear now? – foo_l Jul 22 '13 at 11:16
  • @foo_l check Dmitriy Katkov's solution – MyPasswordIsLasercats Jul 22 '13 at 11:17

4 Answers4

4

If you think about how an array of pointers is stored in memory, you would understand why it can't be done.

Your string array looks like this:

+-------+-------+-------+
| ch[0] | ch[1] | ch[2] |
+-------+-------+-------+
   |       |       |
   |       |       v
   |       |       "abcd"
   |       v
   |       "1.1.1.1"
   v
   "123456782341223344445"

So if you do a memcpy from the ch array you only copy the pointers, not the actual strings.


You can of course copy each string in the array separately into the destination array, but then it's no different than doing it to separate and unrelated strings.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Agreed. But how can I store the strings and others in `arr[512]`? – foo_l Jul 22 '13 at 11:06
  • @foo_l Copy them one by one into the destination array, keeping track of where the next string should begin (`strcpy` and `strlen` are good here). – Some programmer dude Jul 22 '13 at 11:16
  • 1
    @foo_l To copy you can also use: `sprintf(arr, "%s %s %s", ch[0], ch[1], ch[2]);` in single step. (Yes but Joachim Pileborg's suggestion is more better *if you don't know number of strings* ("ip") you wish to copy from `ch[]` and *you will need a loop*) – Grijesh Chauhan Jul 22 '13 at 11:54
  • 1
    @GrijeshChauhan `snprintf` is a better choice, to not risk buffer overflows. – Some programmer dude Jul 22 '13 at 11:58
  • 1
    @JoachimPileborg yes, I forgot to share a [tool](http://www.asciiflow.com/#Draw) with you, your answer says you will like it!! :) – Grijesh Chauhan Jul 22 '13 at 12:11
2

I don't think that's a good idea. Better use structures.

struct info
{
  char* name;
  char* address;
  char* number; // or other type
}

You can use pragma pack if you want to copy full struct to the array. Or use something like copy to combine them.

And if you want to copy it to static array you need to check name length.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
0

You can do so if you memcpy() the strings ch[0] to ch[2] including ithe terminating \0. You can't just memcpy() the complete array ch. To retrieve the second string from within arr you can use strlen() or memchr():

char *ip = arr + strlen(arr) + 1;

or

char *ip = memchr( arr, '\0', sizeof( arr ) ) + 1;

Personally I would prefere the first option, as it is easier to adpopt to get the third string.

Ingo Leonhardt
  • 9,435
  • 2
  • 24
  • 33
0

Beware that uint8_t arr[512] is not the same kind of type as uint8_t *ch[]. The first one is an array of 512 bytes. The second is an array of pointers to bytes. You may have serious problems. So please hep us and tell us what you really want to do.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
  • I just want to store strings and others into the `arr[512]`. So when I try to retrieve them `a[0]` must be `a` `a[1] = b` `a[2] = c` `a[3]=1` `a[4]=1` `a[5]=1` `a[6]=1` `a[7]=1` and so on... – foo_l Jul 22 '13 at 11:11