0

I have a variable which is of type long long int named iData;

iData counts from 1 to its maximum value.

I need to copy this variable to char array.

I tried this below method

long long int iData;
char cDataBuffer[8];

for(i=0;i<8;i++) {
  cDataBuffer[i]= (iData & 0XFF);
  iData = (iData >>8);
}

But I want to store this in dynamic variable in pointer variable char *pDataBuffer.

Can somebody suggest how to store this varying iData variable length.

user3704068
  • 31
  • 1
  • 5
  • By the way, you always get 7 zeroes. You probably want to use `iData >> 8`. – Jongware Jul 06 '14 at 15:55
  • 1
    @Deduplicator: Your method stores `iData` into `cDataBuffer` in host byte order, which can be anything. user3704068's original method (with the correction pointed out by Jongware) will ensure little-endian byte order. – user3553031 Jul 06 '14 at 15:55
  • Could the issue be that OP is confusing "... counts from 1 to its maximum value" with the actual space required for storage? – Jongware Jul 06 '14 at 15:56
  • yes , I don't the size of Idata , its gets incremented after some calculation , so I want to copy this in to char pointer while allocating memory (char pDataBuffer = malloc(sizeoff(Idata)); ) . And copy the Idata .. – user3704068 Jul 06 '14 at 15:57
  • 1
    @user3704068: What do you mean by "I don't the size of Idata"? The size of `iData` is always `sizeof(iData)`; it can't change. – user3553031 Jul 06 '14 at 16:01
  • 1
    @Deduplicator It does not suffice because it invokes undefined behavior by violating the strict aliasing rule. **Don't spread bad practices by recommending it to beginners!** – The Paramagnetic Croissant Jul 06 '14 at 16:47
  • 1
    @Deduplicator No, **you** read that rule (e. g., [here](http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule)). It's OK if you alias **using** `char *` (i. e. `char *p = (char *)&foo`, but it's **not** OK if you alias a `char *` (or anything apart from signed or unsigned `long long *`) using a `long long *` (and that's exactly what you, mistakenly, suggest). – The Paramagnetic Croissant Jul 06 '14 at 17:02
  • @Deduplicator "However this won't work the other way, there's no assumption that your struct aliases a buffer of chars." - says the linked (and accepted) answer. Now what? – The Paramagnetic Croissant Jul 06 '14 at 17:17

2 Answers2

2

Below logic will help you

long long int iData;
char *cDataBuffer;

cDataBuffer = malloc(sizeof(char) * sizeof(iData));

for (i = 0; i < sizeof(iData); i++) 
{
  cDataBuffer[i] = ((iData >> (i * 8)) & 0XFF);
}
  • 3
    Also, [Don't cast the result of malloc (and friends)](http://stackoverflow.com/questions/605845). Anyway, those parentheses around `iData` are useless. And `sizeof(char) * sizeof iData` is also quite curious. `sizeof(char)` is most often a sign that someone has no idea what `sizeof` means. – Deduplicator Jul 06 '14 at 16:12
  • @nix No, that is **wrong.** The C standard **does** require that `sizeof(char)` be one. – The Paramagnetic Croissant Jul 06 '14 at 16:48
  • 1
    In that case the best solution would be sizeof (*cDataBuffer). – Étienne Jul 06 '14 at 16:49
  • @nix [this](http://stackoverflow.com/questions/2215445/are-there-machines-where-sizeofchar-1), aka C99 6.5.3.4. – The Paramagnetic Croissant Jul 06 '14 at 16:52
  • @finalsemester.co.in: Multiplying the return value of `sizeof` with the return value of `sizeof` indicates a thought error. Read `sizeof ...` as "what is the size of ... in `char`". – Deduplicator Jul 06 '14 at 17:08
  • 1
    `sizeof(char)` is always 1 (defined by the ANSI C standard), regardless of `CHAR_BIT` (defined in file limits.h), which is mostly 8 and rarely 16. – barak manos Jul 06 '14 at 17:44
1

If you're not planning to change that copy anywhere (i.e., if you're using it for read-only purposes), then here is a simple solution for you, with a time complexity of O(0):

char* pDataBuffer = (char*)&iData;

Of course, if iData is a local variable, then you cannot use the value of this pointer outside the function.

Also, please note that pDataBuffer[i] will be interpreted differently on different Endian architectures.


If you need a copy of it for write purposes, then you can simply use function memcpy as follows:

char* pDataBuffer = malloc(sizeof(iData));
memcpy(pDataBuffer,&iData,sizeof(iData);
return pDataBuffer;

If possible, then I strongly recommend that you allocate it statically outside the function, and pass as needed.

For example:

void SomeFunction()
{
    ...
    char aDataBuffer[sizeof(iData)];
    SomeOtherFunction(aDataBuffer);
    ...
}

void SomeOtherFunction(char* pDataBuffer)
{
    ...
    memcpy(pDataBuffer,&iData,sizeof(iData);
    ...
}

Otherwise, you'll need to free the allocated memory at some later point in the execution of your program.

Again, keep in mind that pDataBuffer[i] will be interpreted differently on different Endian architectures.

barak manos
  • 29,648
  • 10
  • 62
  • 114
  • It would be worth noting that this doesn't work in the opposite direction (i. e. given a `char data[8]`, one can't say `long long *p = (long long *)data` and dereference `p` then.) – The Paramagnetic Croissant Jul 06 '14 at 17:00
  • @user3477950: I agree that it's a good point to mention that, though slightly different - it would be unsafe to do that on architectures which do not support unaligned load/store operations. – barak manos Jul 06 '14 at 17:06
  • @Deduplicator But that's not what I'm saying. Of course `*(char *)&someLongLong = 42;` is valid. What is not valid is allocating a buffer of chars of size `sizeof(long long)` and then aliasing it through a `long long *`. – The Paramagnetic Croissant Jul 06 '14 at 17:22
  • shucks, you beat me to recommending using memcpy – user3629249 Jul 07 '14 at 02:25