简体   繁体   中英

Concatenating two integer arrays in C

I am trying to concatenate two integer arrays. This method works well for strings (char*), but for integer arrays the content of the second array is changed.

int main() {
  int* a = malloc(8); // 2 integers
  int* b = malloc(12); // 3 integers
  a[0] = 1;
  a[1] = 2;
  b[0] = 3;
  b[1] = 4;
  b[2] = 5;
  int* c = malloc(20); // 5 integers
  memcpy(c, a, 8);
  memcpy(c+8, b, 12);
  printf("%d\n", c[0]); // Excpected 1. Prints 1.
  printf("%d\n", c[1]); // Excpected 2. Prints 2.
  printf("%d\n", c[2]); // Excpected 3. Prints something random.
  printf("%d\n", c[3]); // Excpected 4. Prints something random.
  printf("%d\n", c[4]); // Excpected 5. Prints something random.
  return 0;
}

Forget all about hard-coding variable sizes. That's the root of your problems and makes the code brittle.

The specific problem here though, is that c+8 does pointer arithmetic on an int* . So it means "go 8 int forward from c". Not 8 bytes - it is equivalent to &c[8] , which is obviously wrong.

You should rewrite your code according to this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
  int* a = malloc(2*sizeof(int));
  int* b = malloc(3*sizeof(int));
  a[0] = 1;
  a[1] = 2;
  b[0] = 3;
  b[1] = 4;
  b[2] = 5;
  int* c = malloc(5*sizeof(int));
  memcpy(c, a, 2*sizeof(int));
  memcpy(c+2, b, 3*sizeof(int));
  printf("%d\n", c[0]);
  printf("%d\n", c[1]);
  printf("%d\n", c[2]);
  printf("%d\n", c[3]);
  printf("%d\n", c[4]);
  return 0;
}

An optional syntax for malloc is to do int* a = malloc(2 * sizeof(*a)) , which is fine too, it's a matter of coding style preference.

Due to the pointer arithmetic in this call of memcpy

memcpy(c+8, b, 12);

there is specified an incorrect destination address.

You allocated an array for 5 elements (provided that sizeof( int ) is equal to 4)

int* c = malloc(20)

So due to the pointer arithmetic c + 0 is the address of the first element, c + 1 is the address of the second element, c + 2 is the address of the third element and so on.

As you are trying to fill the array starting from its third element then you have to write

memcpy(c+2, b, 12);
       ^^^^

It is the same as if to write

memcpy( &c[2], b, 12);

Also do not use magic numbers like 12 or 20. Take into account that sizeof( int ) is implementation defined. So it would be much better to write for example

int* c = malloc( 5 * sizeof( int ) );

or

memcpy( c + 2, b, 3 * sizeof( int ) ;

Your program could look the following way.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main( void )
{
    size_t n1 = 2;
    size_t n2 = 3;

    int *a = malloc( n1 * sizeof( int ) );
    int *b = malloc( n2 * sizeof( int ) );

    int init_value = 1;

    for ( size_t i = 0; i < n1; i++ )
    {
        a[i] = init_value++;
    }

    for ( size_t i = 0; i < n2; i++ )
    {
        b[i] = init_value++;
    }

    size_t n3 = n1 + n2;

    int *c = malloc( n3 * sizeof( int ) );

    memcpy( c, a, n1 * sizeof( int ) );
    memcpy( c + n1, b, n2 * sizeof( int ) );

    for ( size_t i = 0; i < n3; i++ )
    {
        printf("c[%zu]: %d\n", i, c[i] );
    }

    putchar( '\n' );

    free( c );
    free( b );
    free( a );

    return 0;
}   

The program output is

c[0]: 1
c[1]: 2
c[2]: 3
c[3]: 4
c[4]: 5

You have to replace memcpy(c+8, b, 12); to memcpy(c+2, b, 12); because first argument of the memcpy function is mean The pointer to the destination array where the content is to be copied, type-casted to a pointer of type void .*

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
  int* a = malloc(8); // 2 integers
  int* b = malloc(12); // 3 integers
  a[0] = 1;
  a[1] = 2;
  b[0] = 3;
  b[1] = 4;
  b[2] = 5;
  int* c = malloc(20); // 5 integers
  memcpy(c, a, 8);
  memcpy(c+2, b, 12);//
  printf("%d\n", c[0]); // Excpected 1. Prints 1.
  printf("%d\n", c[1]); // Excpected 2. Prints 2.
  printf("%d\n", c[2]); // Excpected 3. Prints something random.
  printf("%d\n", c[3]); // Excpected 4. Prints something random.
  printf("%d\n", c[4]); // Excpected 5. Prints something random.
  return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM