【问题标题】:How to change the size of an array and insert another element?如何更改数组的大小并插入另一个元素?
【发布时间】:2020-05-06 08:23:00
【问题描述】:

我有一个数组 0 1 2 4 5 6 7 8 9。 我想在 2 和 4 之间插入 3。

调用函数后长度保持不变,即使我添加了一个值,为什么?

printf("%d,", feld[9]); 给了我正确的值,代码有效 - 但我收到警告。

即使我使用int feld[9] = {0,1,2,4,5,6,7,8,9};int feld[] = {0,1,2,4,5,6,7,8,9}; 进行初始化,如何插入值?


nt insertArray(int* array, int length, int value, int pos) 
{
    int i;

    if (pos < length)
    {
        for (i = length; i > pos; i--)
        {
            array[i] = array[i - 1];
        }
        array[i] = value;
        length++;
    }

    else if (pos == length)
    {
        array[pos] = value;
        length++;
    }
    return length;
}


int main()
{
    int feld[9] = {0,1,2,4,5,6,7,8,9};

    size_t length = sizeof(feld) / sizeof(int);

    insertArray(feld, length, 3, 3);

    length = sizeof(feld) / sizeof(int);

    for (int i = 0; i < length; i++)
    {
        printf("%d,", feld[i]);
    }
    printf("\n");

    printf("%d,", feld[9]);

    return 0;
}

【问题讨论】:

  • 您想在两者之间添加一个额外的元素,对吧?不只是交换已经存在的吗?如果是这种情况,你不能在 C 中这样做,因为数组是固定大小的,因此你不能随意添加元素。
  • @Tilo 该程序具有未定义的行为。您不能扩大数组。
  • 不能扩展固定数组的长度,也许可以预留更多的内存或者去动态内存,这两种情况你都得自己记住实际的项数。
  • “但我收到警告”:嗯,哪个警告??
  • 好问题@Jabberwocky :-):警告:数组索引 9 超出了数组的末尾(包含 9 个元素)[-Warray-bounds]

标签: c arrays memory insert


【解决方案1】:

根据 C 语法,不允许在定义后修改静态分配数组的长度。任何这样做的尝试都会调用undefined behavior

相反,使用malloc() 分配动态内存,使用指针偏移量访问某些伪元素并使用realloc() 调整内存大小。

将元素49 的内容复制到元素510。现在您可以将3 存储在4th 元素中。

一个示范性例子:

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

#define SIZE 9
#define ELEM_TO_CH 4

int main(void)
{
    int* feld_ptr = malloc(sizeof(int) * SIZE);
    if(!feld_ptr)
    {
       fprintf(stderr,"Memory could not be allocated for feld_ptr!");
       return 1;
    }

    for(int i = 0; i < SIZE; i++)
    {
       if (i > (ELEM_TO_CH - 2))
          feld_ptr[i] = i + 1;
       else
          feld_ptr[i] = i;
    }

    printf("Before:\n\n");
    for(int i = 0; i < SIZE; i++)
    {
       printf("feld_ptr[%d] = %d\n", i, feld_ptr[i]);
    }

    printf("\n\n");

    feld_ptr = realloc(feld_ptr, SIZE + 1);
    if(!feld_ptr)
    {
       fprintf(stderr,"Error at resizing memory pointed by feld_ptr!");
       return 1;
    }

    memcpy(&feld_ptr[ELEM_TO_CH], &feld_ptr[ELEM_TO_CH-1], sizeof(int) * ((SIZE + 1) - ELEM_TO_CH));

    feld_ptr[ELEM_TO_CH-1] = 3;

    printf("After:\n\n");
    for(int i = 0; i < (SIZE + 1); i++)
    {
        printf("feld_ptr[%d] = %d\n", i, feld_ptr[i]);
    }

    free(feld_ptr);

    return 0;
}

输出:

Before:

feld_ptr[0] = 0
feld_ptr[1] = 1
feld_ptr[2] = 2
feld_ptr[3] = 4
feld_ptr[4] = 5
feld_ptr[5] = 6
feld_ptr[6] = 7
feld_ptr[7] = 8
feld_ptr[8] = 9

After:

feld_ptr[0] = 0
feld_ptr[1] = 1
feld_ptr[2] = 2
feld_ptr[3] = 3
feld_ptr[4] = 4
feld_ptr[5] = 5
feld_ptr[6] = 6
feld_ptr[7] = 7
feld_ptr[8] = 8
feld_ptr[9] = 9

【讨论】:

    【解决方案2】:

    您需要为您的任务使用堆而不是堆栈。

    正如您帖子下方的 cmets 所述,如果您声明数组,它将具有固定大小。当然,您可以编辑它并添加另一个值,但请记住您在内存中分配了一些与您的数组不对应的额外空间,从而破坏了堆栈中的一些其他变量(可能)这是不安全的。

    您可以使用malloc() 在堆中保留所需的内存量,然后使用realloc() 函数来更改初始大小。 记得在程序结束时free()内存。

    【讨论】:

      【解决方案3】:

      和上面的 cmets 一样,你不能扩展数组的大小。在这种情况下,我提出了两种解决方案:

      1. 在插入函数中使用指针。在这种情况下,您必须使用size = length of old array + 1 为该指针分配。插入函数变为:
      int * insertArray(int* arr, int length, int value, int pos) 
      {
          int * array = malloc(sizeof(int) * (length + 1));
          if(!array) {
             return NULL;
          }
          for(int i = 0; i < length; i++) {
              array[i] = arr[i];
          }
          int i;
      
          if (pos < length)
          {
              for (i = length; i > pos; i--)
              {
                  array[i] = array[i - 1];
              }
              array[i] = value;
              length++;
          }
      
          else if (pos == length)
          {
              array[pos] = value;
              length++;
          }
          return array;
      }
      
      

      然后在主函数中:

      int main()
      {
          int feld[9] = {0,1,2,4,5,6,7,8,9};
      
          size_t length = sizeof(feld) / sizeof(int);
      
          int * array = insertArray(feld, length, 3, 3);
      
          for (int i = 0; i <= length; i++)
          {
              printf("%d,", array[i]);
          }
          free(array);
          return 0;
      }
      
      1. 在主函数中使用指针而不是数组,然后在插入函数中重新分配指针。
      void insertArray(int* array, int length, int value, int pos) 
      {
          array = realloc(array, sizeof(int) * (length + 1));
          if (!array)
             return;
          ...
      }
      

      在主函数中:

      int main()
      {
          int *feld = malloc(sizeof(int) * 9);
          if(!feld)
            return -1;
      
          for(int i = 0; i < 9; i++) {
              if(i<3)
                feld[i] = i;
              else
                feld[i] = i+1;
          }
      
          insertArray(feld, 9, 3, 3);
      
          for (int i = 0; i <= 9; i++)
          {
              printf("%d,", feld[i]);
          }
          free(feld);
          return 0;
      }
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-17
        • 2022-10-23
        • 1970-01-01
        • 1970-01-01
        • 2022-01-16
        • 2011-08-22
        • 1970-01-01
        • 2015-08-30
        相关资源
        最近更新 更多