![](/img/trans.png)
[英]Assigning value to an index in a struct pointer array inside of a struct pointer
[英]Assigning struct array to pointer
我已经初始化了一个结构数组(仅包含一个名为name
的字符字符串。然后将该结构数组分配给一个指针,如下所示:
location locations[2] = {{"Padstow", 50.5384, -4.9378},
{"Newquay", 50.412, -5.0757}};
int location_size = 2;
location *loc_ptr;
loc_ptr = &locations[0];
// pick an element to remove
location element = loc_ptr[1];
remove_element(loc_ptr, location_size, element);
然后,我将此指针传递给一个函数。 在此函数内部,我正在删除数组的元素。 这可以通过遍历当前数组并创建一个新数组来完成。 新数组包含我期望的数据。
在remove_element
函数内部:
void remove_element(location *ptr, int count, location element) {
// create the new array
location new_locations[count-1];
// go through and pick out the non-matching element
// create the new pointer
location *new_ptr;
new_ptr = &new_locations[0];
// assign the new array to the original pointer
ptr = new_ptr;
}
但是,它不会更改原始数据。 您能解释一下我为将这个新数组分配给原始指针所做的错误操作吗?
我已经有一段时间没有用C做任何事了,所以我有点生锈,但是我会尝试一下...
我将看到(至少)两种方法可以使此工作正常进行:从函数返回新数组的新指针,并将其存储在旧指针中,例如(在语法上可能不正确):
loc_ptr = someFunctionCreatingTheNewArrayAndReturningAPointerToIt(loc_ptr);
另一种可能性是将loc_ptr传递给函数的按指针而不是按值。 基本上,您将“指针到指针”作为参数传递给函数,指针到指针指向loc_ptr。 在函数内部,可以从指针到指针解引用数组的内存地址以访问原始数组。 创建并填充新数组后,将新数组的内存地址放入由指针传递的参数中。
编辑:我整理了两种方法的快速示例,这实际上是在C ++中,但是我99%确信,指针在C中的工作原理相同(对不起,如果有点冗长)。 请注意,数组不会在任何地方释放,因此这会导致内存泄漏(但是您应该获得传递按值与按指针传递的想法):
#include <iostream>
#include <string.h>
struct location
{
std::string name;
double lat;
double lon;
};
location* createNewArrayAndReturnPointer(location* loc)
{
std::cout << "-- Replacing array, name of the first location in old array is " + loc->name << std::endl;
location* newLoc = new location[2]; //Local pointer-variable, creating new array and storing array address to it
newLoc[0].name = "Replacing pointer by return value";
return newLoc; //Return new pointer
}
void modifyViaGivenPointerToPointer(location** loc_ptr_to_ptr)
{
location* loc = *loc_ptr_to_ptr; //De-referencing the array address from the pointer-to-pointer, storing to local pointer-variable
std::cout << "-- Modifying pointer, name of the first location pointed originally is " + loc->name << std::endl;
location* newLoc = new location[2]; //Creating new array and storing to local pointer-variable
newLoc[0].name = "From modifyViaGivenPointerToPointer";
*loc_ptr_to_ptr = newLoc; //Replacing the contents of given pointer-variable via dereference
}
void printNameOfFirstLocationInArray(location* loc_ptr)
{
std::cout << "The name of the first location pointer by loc_ptr is now " << loc_ptr->name << std::endl;
}
int main(void)
{
location locations[2] = {{"Padstow", 50.5384, -4.9378},
{"Newquay", 50.412, -5.0757}};
location* loc_ptr;
loc_ptr = &locations[0];
printNameOfFirstLocationInArray(loc_ptr);
//Returns new pointer from function and store it in the pointer-variable
loc_ptr = createNewArrayAndReturnPointer(loc_ptr);
printNameOfFirstLocationInArray(loc_ptr);
//Modifies the passed pointer-to-pointer, so it points to the new array after returning
modifyViaGivenPointerToPointer(&loc_ptr);
printNameOfFirstLocationInArray(loc_ptr);
return 0;
}
输出为:
loc_ptr的第一个位置指针的名称现在为Padstow
-替换阵列,旧阵列中第一个位置的名称为Padstow
loc_ptr的第一个位置指针的名称现在是按返回值替换指针
-修改指针,最初指向的第一个位置的名称是用返回值替换指针
loc_ptr的第一个位置指针的名称现在为From ModifyViaGivenPointerToPointer
您如何从函数中返回新数组 。
如果要更改数组所在的地址 ,则需要一个双指针(指向指针的指针)。
这不起作用:
void f(location *l)
{
// changing the array here:
l = malloc(5*(sizeof(location));
// add new stuff to l
}
int main()
{
location *loc_ptr;
loc_ptr = &locations[0];
f(loc_ptr); // won't change address loc_ptr's is pointing to.
}
如果你有:
struct location a;
struct location b;
a = b;
您将把b
中的数据复制到a
。
您似乎正在执行以下操作:
struct location *a;
struct location *b;
a = b;
这会将b
的指针复制到a
; 不是数据。
您可能的意思是:
*ptr = *new_ptr;
将new_ptr
指向的数据复制到ptr
指向的位置。
当你做
ptr = new_ptr;
我假设ptr
是您函数的参数。 您实际上所做的是覆盖堆栈上的值(指针本身的值),这不会更改函数外部的指针值。 您可以传回新指针,也可以将指向“位置”的双指针作为参数,然后执行以下操作:
*p_ptr = new_ptr;
如果要通过location
变量反映对阵列的更改,则需要直接就地修改该阵列。 如果您希望对数组的副本进行所有更改,那很好,但是您必须遍历整个数组并将所有结构复制回到第一个数组。
要非常小心,以保持数组长度相同,或者始终将数组长度变量保持在永不增长的位置。 C数组不会增长。 您可以尝试使用realloc(3)
进行realloc(3)
,但可能会失败,并且首先必须使用malloc(3)
分配原始文件。 它们可以收缩,有点,如果您只是假装它们更短... :)
我认为您正在按以下顺序进行操作
void f(location *loc_ptr)
{
location *new_array = ...
loc_ptr = new_array;
}
int main(void)
{
location locations[2] = {...};
location *loc_ptr = locations;
f(loc_ptr);
...
}
如果是这样,解决方案是
void f(location **loc_ptr)
{
location *new_array = ...;
*loc_ptr = new_array;
}
int main(void)
{
location locations[2] = {...};
location *loc_ptr = locations;
f(&loc_ptr);
...
}
如果要更改loc_ptr
的值而不是loc_ptr
指向的值, loc_ptr
必须将指向它的指针传递给函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.