【问题标题】:How to manually fill an integer array that has been dynamically allocated via an integer pointer?如何手动填充已通过整数指针动态分配的整数数组?
【发布时间】:2020-09-30 18:43:59
【问题描述】:

我已经动态分配了一个指向整数的指针——它是一个数组——我想用一组特定的数字填充这个数组。

int * myArr= (int*)malloc(SIZE_OF_ARRAY * sizeof(int));

if (myArr == NULL) {
    return EXIT_FAILURE;
}

*myArr = {452,35,351,53,66};

我也尝试了其他选项:

myArr[] = {452,35,351,53,66};
myArr[5] = {452,35,351,53,66};

但问题是一样的。

【问题讨论】:

  • 一个一个。或者来自另一个数组的memcpy(在你的情况下可能毫无意义)。
  • 你想要的功能是 memset ,这会让你去stackoverflow.com/questions/7202411/…
  • 顺便说一句,因为这是C,而不是C++,所以:int * myArr= (int*)malloc(SIZE_OF_ARRAY * sizeof(int)); 可以(and should be)简化为int * myArr= malloc(SIZE_OF_ARRAY * sizeof(*myArr));(主要指演员阵容,但如果对为什么我还更改了sizeofread this 的论点感兴趣)。
  • 你真的需要动态分配这个,还是只是一个指针类型,设置为指向一个初始化块?如果是后者,那么int *p = &initializer_block; 将无需额外的动态分配成本即可工作。

标签: arrays c dynamic-memory-allocation


【解决方案1】:

您可以使用具有初始值的数组中的memcpy()

static const int initial_values[] = {452, 35, 351, 52, 66};
memcpy(myArr, initial_values, sizeof(initial_values));

数组不能直接相互分配,因为当它们在 R 值上下文中使用时,它们会衰减为指向第一个元素的指针。

【讨论】:

  • 谢谢!虽然这个解决方案有效,但我想知道为什么不能直接将整数数组分配给以前动态分配的指向 int 数组的指针?
  • 因为数组不是你可以分配的东西。
  • 一个数组衰减为指向它在右值上下文中的第一个元素的指针。
  • 这有双重开销(如果在函数中使用)。 1) inital_values 分配在堆栈上 2) 它的初始化程序是静态分配的 3) 初始化发生在运行时
  • 如果出现问题,您可以将其设为静态以避免所有开销。
【解决方案2】:

在第一个答案下在 cmets 中解决您的问题:“为什么不能将整数数组直接分配给以前动态分配的指向 int 数组的指针”,也可以使用这个方法(不使用动态分配的内存,但确实使用了设置为数组地址的指针类型:

int initial_values[] = {452,35,351,53,66};
int *pMyArray = &initial_values[0]; //sets pointer to address of array[0]

现在你有了一个指针类型,指向包含相同内容的有效内存,无需分配内存,也无需释放分配的内存。

(这个确切的方法也是described here)。

编辑回答 cmets 中的问题“这有什么意义?...
...如果你不需要它是动态的,你可以使用 initial_values 作为指针。”

简短的回答是提供与某些函数原型的兼容性,同时不需要动态分配。指针类型会编译和运行,数组类型不会。即,即使initial_values 指向数组的地址,&initial_values 也不使其与int **a 兼容,而&pMyArray 是兼容的。

下图使用s_test tests_test *p 作为类型来替换initial_valuespMyArray

typedef struct {
    int iVal;
    double dVal;
    char sVal[10]
}s_test;
#define SIZE 5
void func(s_test **t, size_t size)
{ 
    const char *new[10] = {"new1","new2","new3","new4","new5"};
    for(int i=0;i<size;i++)
   {
        (*t)[i].iVal *=10;
        (*t)[i].dVal *=10.0;
        strcpy((*t)[i].sVal, new[i]);
   }
}
int main(void)
{
    s_test test[SIZE] = {{1, 1.0, "string1"},
                     {2, 2.0, "string2"},
                     {3, 3.0, "string3"},
                     {4, 4.0, "string4"},
                     {5, 5.0, "string5"}};
    
    s_test *p = &test[0];

    func(&p, SIZE); //this works using pointer to pointer
    func(&test, SIZE);//run-time error, general protection
    
    return 0;   
}

【讨论】:

  • 这有什么意义?如果您不需要它是动态的,您可以使用initial_values 作为指针。
  • @Barmer - 这引出了一个问题,为什么首先分配内存呢?但是好的一点,我已经使用这个方法来初始化指针变量,我随后将作为需要type ** 参数的函数参数传递,即修改由现有结构数组初始化的结构内容。而且,我想以相同的方式使用结构数组会很好,因为它的名称本质上是指向其内存地址的指针。但你是对的,除了 它有效 我不能断言更多:)
  • 我认为动态分配是因为大小需要是动态的,或者他们需要使用realloc() 来调整它的大小,或者数组必须超过局部变量的生命周期——所有这些都是常见的使用malloc() 的原因。他要做的就是在分配时初始化内容。
  • @Barmer - 是的,动态分配的原因是一个假设,但对您的问题并不重要。我进行了一些测试以提醒自己为什么之前使用它(请参阅最后一条评论。)请参阅编辑以回答您的问题有什么意义....看到您的评论后,我对您的评论很感兴趣。跨度>
猜你喜欢
  • 2019-06-24
  • 2017-01-19
  • 2023-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-16
相关资源
最近更新 更多