1

I need some guidence on pointers and array's

char *ptr;
char Array1[20];

ptr = malloc(sizeof(Array1));

now how can i get the entire Array1 into the ptr??

I have tried strcat, strncat, strcpy. Also i tried a loop then using the mentioned functions and adding each element of th array and nothing

int a = 0
while ( a <= sizeof(Array1) )
{
     strcpy(ptr, Array1[a]);
     a++; 
}

I really need to know how to get the array into a pointer.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483

3 Answers3

9

Use memcpy():

ptr = malloc(sizeof(Array1));
if (ptr)
{
    memcpy(ptr, Array1, sizeof(Array1));
}

The str* family of functions are dependent upon the presence of null terminator characters.

If Array1 does contain a string, terminated by a null character, then strcpy() and strncpy() would operate correctly. strcat() requires the presence of a null terminator in the destination buffer as well as the source buffer to function correctly.

If Array1 does not contain a null terminated string then do not use the str* functions, use memcpy() instead.

hmjd
  • 120,187
  • 20
  • 207
  • 252
  • 1
    +1 but extra brownie points if you point out why you can't use strcpy and strncpy. – Bathsheba Apr 16 '14 at 13:29
  • `strncpy` could be used, and may even be better than `memcpy` if `Array1` is supposed to contain a string – M.M Apr 16 '14 at 13:33
  • 1
    @MattMcNabb `strncpy` has no advantages over `memcpy`. If `Array1` is correctly nul terninated, everything OK. But if not, `strncpy` wont fix it. – user694733 Apr 16 '14 at 13:40
  • `strncpy` has the advantage that it does not read junk in the source array that comes after the null terminator (if there was one). Heartbeat? :) – M.M Apr 16 '14 at 13:41
  • There are two cases where you use strncpy: 1) you are some hardened UNIX veteran programming 40 years old computers, or 2) you are confused. [strncpy() was never a safer version of strcpy()](http://stackoverflow.com/questions/2114896/why-is-strlcpy-and-strlcat-considered-to-be-insecure), that's just an urban legend created by confused people, so that they sound smart when they speak to even more confused people. On the contrary, strncpy() is a dangerous function. [More info about why strncpy is dangerous and unsafe](http://randomascii.wordpress.com/2013/04/03/stop-using-strncpy-already/). – Lundin Apr 16 '14 at 13:45
1

now how can i get the entire Array1 into the ptr??

Use memcpy:

memcpy(ptr, Array1, sizeof(Array1));

Also I tried a loop then using the mentioned functions and adding each element of th array

That loop is incorrect, because you are treating an array of chars as an array of char*.

I really need to know how to get the array into a pointer.

The name of the array converts freely to a pointer to the initial array element. That is why you can pass Array1 to memcpy, which takes a pointer. In general, Array1 expression is the same as &Array1[0], which is the explicit way of taking the address of the initial array element.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

For added hilarity, you can do it entirely without getting your hands or the standard library's hands dirty with pesky loops and let the compiler do the hard work:

#include <stdio.h>
#include <stdlib.h>
int main() {
  char a[20] = "Hello World today!!";
  char* const p = malloc(sizeof a); 
  union {
    char* volatile p;
    struct {
      char a[20];
    }* s;
  } destination = {.p = p}, source = {.p = a}; 
  *destination.s = *source.s;
  printf("%s\n",p);
  return 0;
}
// tested with CFLAGS:='-Wall -Wextra -pedantic -std=c11'

Although it should be mentionend that this is not technically compliant with the C standard specification, because we're hiding a cast by using a union and the standard doesn't allow us to use unions in this way (you have to promise to only use the union member that you last wrote to, which we break when using the s member).

But it's more fun than using the library or those loop things, don't you agree? :)
(Disclaimer: This is using loops, too (or rather implicitly unrolled loops). We just don't see them.)


Edit I was just curious and had a look at what clang (3.2, rather dated, granted) generates from this and it seems to actually translate this into a memcpy call (last line).

  %1 = alloca i32, align 4
  %a = alloca [20 x i8], align 16
  %p = alloca i8*, align 8
  %destination = alloca %union.anon, align 8
  %source = alloca %union.anon, align 8
  store i32 0, i32* %1
  %2 = bitcast [20 x i8]* %a to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* getelementptr inbounds ([20 x i8]* @main.a, i32 0, i32 0), i64 20, i32 16, i1 false)
  %3 = call noalias i8* @malloc(i64 20) nounwind
  store i8* %3, i8** %p, align 8
  %4 = bitcast %union.anon* %destination to i8**
  %5 = load i8** %p, align 8
  store volatile i8* %5, i8** %4, align 8
  %6 = bitcast %union.anon* %source to i8**
  %7 = getelementptr inbounds [20 x i8]* %a, i32 0, i32 0
  store volatile i8* %7, i8** %6, align 8
  %8 = bitcast %union.anon* %destination to %struct.anon**
  %9 = load %struct.anon** %8, align 8
  %10 = bitcast %union.anon* %source to %struct.anon**
  %11 = load %struct.anon** %10, align 8
  %12 = bitcast %struct.anon* %9 to i8*
  %13 = bitcast %struct.anon* %11 to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %12, i8* %13, i64 20, i32 1, i1 false)
bitmask
  • 32,434
  • 14
  • 99
  • 159