C-将指针传递给一个函数,然后在函数内部将同一指针传递给另一个函数
唷!长标题…下面是一些伪代码来解释这种说法:C-将指针传递给一个函数,然后在函数内部将同一指针传递给另一个函数,c,function,pointers,C,Function,Pointers,唷!长标题…下面是一些伪代码来解释这种说法: int main(){ int* ptr = function1(); //the data that ptr points to is correct here function2(ptr); } int function2(int* ptr){ //the data that ptr points to is still correct int i; for(i=0;i<length;printf("%d\n", (*ptr)[i]),
int main(){
int* ptr = function1(); //the data that ptr points to is correct here
function2(ptr);
}
int function2(int* ptr){
//the data that ptr points to is still correct
int i;
for(i=0;i<length;printf("%d\n", (*ptr)[i]), i++); //since ptr points to a contiguous block of memory
function3(ptr);
}
int function3(int* ptr){
//the data that ptr points to is INCORRECT!!!
}
为什么函数3中的数据不正确
注意:function1执行malloc并返回指向该内存的指针
实际代码
#include <stdlib.h>
#include <stdio.h>
//Structures
struct hash_table_data_
{
int key, data;
struct hash_table_data_ *next, *prev;
};
struct hash_table_
{
int num_entries;
struct hash_table_data_ **entries;
};
typedef struct hash_table_data_ hash_table_data;
typedef struct hash_table_ hash_table;
//Prototypes
hash_table *new_hash_table(int num_entries);
int hash_table_add(hash_table *ht, int key, int data);
int hash_table_loader(hash_table* ht);
//Main
int main()
{
int num_entries = 8;//THIS MUST BE AUTOMATED
hash_table* ht = new_hash_table(num_entries);
hash_table_loader(ht);
return 0;
}
//Function Definitions
hash_table *new_hash_table(int num_entries)
{
hash_table* ht = (hash_table*) malloc(sizeof(hash_table));
hash_table_data* array = malloc(num_entries * sizeof(hash_table_data));
int i;
for (i=0;i<num_entries;i++)
{
array[i].key = -1;
array[i].data = -1;
array[i].next = NULL;
array[i].prev = NULL;
}
ht->entries = &array;
ht->num_entries = num_entries;
return ht;
}
int hash_table_add(hash_table *ht, int key, int data)
{
//VERIFY THAT THE VALUE ISN'T ALREADY IN THE TABLE!!!!!!!!!!!
int num_entries = ht->num_entries;
hash_table_data* array = *(ht->entries); //array elements are the LL base
int hash_val = key%num_entries;
printf("adding an element now...\n");
printf("current key: %d\n", array[hash_val].key);
int i;
for(i=0;i<num_entries;printf("%d\n", (*(ht->entries))[i].key),i++);//DATA IS INCORRECT!!!!
if (array[hash_val].key == -1)//is this the base link?
{
printf("added a new base link!\n");
array[hash_val].key = key;
array[hash_val].data = data;
array[hash_val].next = NULL;
array[hash_val].prev = &(array[hash_val]);
}
else//since it's not the base link...do stuff
{
hash_table_data* new_link = malloc(sizeof(hash_table_data));
new_link->key = key;//set the key value
new_link->data = data;//set the data value
if (array[hash_val].next == NULL)//we must have the second link
{
printf("added a new second link!\n");
new_link->prev = &(array[hash_val]); //set the new link's previous to be the base link
array[hash_val].next = new_link; //set the first link's next
}
else//we have the 3rd or greater link
{
printf("added a new 3rd or greater link!\n");
hash_table_data next_link_val = *(array[hash_val].next);
while (next_link_val.next != NULL)//follow the links until we reach the last link
{
next_link_val = *(next_link_val.next);//follow the current link to the next
}
//now that we've reached the last link, link it to the new_link
next_link_val.next = new_link; //link the last link to the new link
new_link->prev = &(next_link_val); //link the new link to the last link
}
}
return 0;
}
int hash_table_loader(hash_table* ht)
{
int i;
for(i=0;i<(ht->num_entries);printf("%d\n", (*(ht->entries))[i].key),i++); //DATA IS STILL CORRECT HERE
FILE *infile;
infile = fopen("input.txt", "r");
while(!feof(infile))
{
int key,data;
fscanf(infile, "%d %d", &key, &data);
hash_table_add(ht, key, data);
}
fclose(infile);
}
注意:第一次调用hash_table_add时出现问题。我猜您的迭代不正确
for(i=0;i<length;printf("%d\n", (*ptr)[i]), i++);
这是胡说八道
您应该将其改写为:
for(i=0;i<length;i++)
printf("%d\n", ptr[i]);
*ptr[i]是错误的,如果你仔细想想,它是没有意义的
*ptr是指向int数组的第一个元素。
ptr[i]就是这个,这就是你需要的
请仔细阅读
基于这个问题的几点建议:
不要像这样为使用逗号运算符的语句编写过于复杂的代码,它很少需要,而且不仅会导致混淆,还会导致错误,尽管在这个特定示例中没有错误
仔细查找错误,不要把一切都归咎于函数。如果你的代码不起作用,试着找出错误的确切位置并加以证明。在这个例子中,测试代码的人是对的:函数绝对不是错误的原因。
您的第一个问题是: ht->entries=&array 使结构保存一个哈希表数据**,它指向函数的本地变量哈希表数据*数组;然后退出函数并返回指向该结构的指针。结构仍然存在,它是通过malloc分配的,数组指向的内容仍然存在,但数组本身并不存在。因此,结构中的此指针现在无效 据我所知,你没有理由在这里拿着指向指针的指针。只需使用hash_table_data*作为条目类型,并将数组复制到该结构成员中。指针也是值
hash_table *new_hash_table(int num_entries)
{
hash_table* ht = (hash_table*) malloc(sizeof(hash_table));
hash_table_data* array = malloc(num_entries * sizeof(hash_table_data));
// ....
ht->entries = &array; // Problem
// ...
return ht;
} // Life time of array ends at this point.
您正在获取局部变量数组的引用,并将其分配给ht->entries,一旦函数返回,这些项就不再有效。这是优化代码吗?你怎么知道ptr不正确?显示函数1的定义。要么你的编译器坏了,要么你的cpu坏了?忘记函数1,我想看看你在函数3中的代码。不,等等,我想看看您是如何检查function2中的数据的,您可能无意中更改了指针。这似乎是您实际代码的一个过于简化的示例。我并不急于通过数千行代码查找您的错误,但可能就是这样,除非您可以提供另一个示例来显示您建议的错误,或者提供给出错误的确切代码的屏幕截图。entries是指向指针的指针,因此将其指定为ht->entries=&array;另外,数组指向连续内存块中的第一个块。@nick\u name:只要您在函数的作用域内,它就有意义。数组驻留在堆栈上,但数组指向的值驻留在堆上。一旦函数返回,驻留在堆栈上的变量就会被销毁。从这个意义上讲,这与赋值无关。您只考虑了类型检查:即间接寻址的级别数是否匹配。有一个逻辑错误-数组的持续时间不如ht->entries长,因此ht->entries可能不会指向数组-并且是语义错误-条目首先是指向指针的指针是没有意义的。很好!谢谢“我正在测试这个变化。”卡尔,看我的评论,我在他发布实际代码之前发布了答案