【问题标题】:Concatenating two integer arrays in C在C中连接两个整数数组
【发布时间】:2020-08-29 09:41:41
【问题描述】:

我正在尝试连接两个整数数组。此方法适用于字符串 (char*),但对于整数数组,第二个数组的内容会发生变化。

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;
}

【问题讨论】:

    标签: c arrays integer memcpy pointer-arithmetic


    【解决方案1】:

    忘记所有关于硬编码变量大小的事情。这是您问题的根源,并使代码变得脆弱。

    这里的具体问题是c+8 int* 上进行指针运算。所以它的意思是“从 c 向前走 8 int”。 不是 8个字节——相当于&c[8],这显然是错误的。

    你应该根据这个重写你的代码:

    #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;
    }
    

    malloc 的可选语法是 int* a = malloc(2 * sizeof(*a)),这也很好,这是编码风格偏好的问题。

    【讨论】:

      【解决方案2】:

      由于这个memcpy调用中的指针算法

      memcpy(c+8, b, 12);
      

      指定的目标地址不正确。

      你为 5 个元素分配了一个数组(前提是 sizeof(int) 等于 4)

      int* c = malloc(20)
      

      所以由于指针运算c + 0是第一个元素的地址,c + 1是第二个元素的地址,c + 2是第三个元素的地址,依此类推。

      当您尝试从第三个元素开始填充数组时,您必须编写

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

      好像写一样

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

      也不要使用像 12 或 20 这样的幻数。考虑到 sizeof(int) 是实现定义的。所以写例子会好很多

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

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

      您的程序可能如下所示。

      #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;
      }   
      

      程序输出是

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

      【讨论】:

        【解决方案3】:

        您必须将memcpy(c+8, b, 12); 替换为memcpy(c+2, b, 12);,因为memcpy 函数的第一个参数是意思指向要复制内容的目标数组的指针,类型转换为键入 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;
        }
        

        【讨论】:

          猜你喜欢
          • 2012-09-23
          • 1970-01-01
          • 2023-02-09
          • 2010-12-14
          • 2016-09-07
          • 1970-01-01
          • 2011-05-08
          • 1970-01-01
          相关资源
          最近更新 更多