Int 指针不为空,可以打印,但不能在不引发分段错误的情况下传递给函数
Posted
技术标签:
【中文标题】Int 指针不为空,可以打印,但不能在不引发分段错误的情况下传递给函数【英文标题】:Int pointer is not null and can be printed but can not be passed into a function without throwing a segmentation fault 【发布时间】:2018-01-26 02:04:58 【问题描述】:我正在为一个 int 指针分配一个从 sscanf
提取的值。然后我想将它传递给来自不同文件counters_add
的方法。虽然我可以打印出存储在指针中的值及其地址,但只要我将它传递给这个方法,程序就会抛出一个段错误。从测试中我知道程序在段错误之前甚至没有进入这个方法。
这个方法接受(counters_t *ctrs, const int key)
的参数。 counters_t
对象是我在文件前面定义的结构。
我不会过早地释放任何东西,并且已经验证ctrs
和key
都不是NULL
。为什么会出现分段错误?
int *key = malloc(sizeof(int));
//check if key is null here
sscanf(line, "%i", key);
printf("key: %i\n", *key); //this prints out the value
printf("key: %p\n", (void *)key); //this prints out the address
counters_add(ctrs, *key);//seg fault here, without even getting inside of method
ctrs的初始化:
counters_t *ctrs = count_malloc(sizeof(counters_t));
if (ctrs == NULL)
return NULL; // error allocating set
else
// initialize contents of set structure
ctrs->head = NULL;
其余代码:
void
counters_add(counters_t *ctrs, const int key)
if (key >= 0 && ctrs != NULL)
// allocate a new node to be added to the list if the key is not already in the set
if(counters_get(ctrs,key) == 0) //if it doesnt already exist
printf("after first if statement");
counternode_t *new = counternode_new(&key);//create it
printf("aftermaking new node");
new->next = ctrs->head;//add it to the head of the list
ctrs->head = new;
else
// increment the count
for(counternode_t *curr = ctrs->head; curr != NULL; curr = curr->next)
if (*(curr->key) == key)
*(curr->count) = *(curr->count) + 1;
int
counters_get(counters_t *ctrs, const int key)
printf("in counters_get");
if (ctrs == NULL)
return 0; // null counter
else if (ctrs->head == NULL)
return 0; // set is empty
//remove this in set
else
for(counternode_t *curr = ctrs->head; curr != NULL; curr = curr->next)
if (*(curr->key) == key)
return *(curr->count);
printf("in loop");
return 0;
static counternode_t // not visible outside this file
*counternode_new(const int *key)
counternode_t *node = count_malloc(sizeof(counternode_t));
int *newkey = (int*)malloc(sizeof(int));
newkey = (int*) memcpy(newkey, key, (50 * sizeof(char)));
//make sure key is not over 50 ints
if (node == NULL || newkey == NULL)
// error allocating memory for node or new key; return error
return NULL;
else
node->key = newkey;
*(node->count) = 1;
node->next = NULL;
return node;
这是计数器结构:
typedef struct counters
struct counternode *head; // head of the list of items in set
counters_t;
这里是countersnode:
typedef struct counternode
int *key;
int *count; //pointer to counter for this node
struct counternode *next; // link to next node
counternode_t;
【问题讨论】:
问题很可能在于ctrs
。你是怎么声明ctrs
的?你初始化了吗?
请创建一个minimal reproducible example。
counters_add
有原型吗?
"我在之前的代码中声明了ctrs,并为其声明了malloc内存。我还检查它是否为null。" -- 不要告诉我们,给我们看。我们应该能够从问题中复制并粘贴您的代码并自己运行以重现问题。
不要只是添加多个不连贯的代码块。从显示问题的程序开始,尽可能缩小范围,使其仍然显示相同的问题。您应该能够将其缩短到 20 行左右。然后将该完整的程序作为单个代码块发布。正如我所说,我们应该能够复制并粘贴您的整个程序并自己重现问题。我不愿意复制和粘贴当前问题中的 7 块代码中的每一个,并弄清楚如何将它们重新组合在一起。
【参考方案1】:
我在counternode_new
看到了问题:
static counternode_t // not visible outside this file
*counternode_new(const int *key)
counternode_t *node = count_malloc(sizeof(counternode_t));
int *newkey = (int*)malloc(sizeof(int));
newkey = (int*) memcpy(newkey, key, (50 * sizeof(char)));
...
在counters_add
中,您将一个指向变量d
的指针传递给counternode_new
。
然后在counternode_new
中,你想用key
复制newkey
50 个字节为
来源。但是key
是指向 single 整数的指针,所以你读的是 49
字节超出范围,这会导致未定义的行为,这可能会导致
段错误。此外,您仅为newkey
的单个int
分配空间。此外,您正在复制 50 个字节,而不是 50 个整数。我不明白 50 是从哪里来的。
所以你的counternode_new
调用counters_add
没有意义,首先你必须
为int[50]
数组分配空间并将其传递给counternode_new
。
【讨论】:
这似乎是正确的,这是一个很大的错误,所以我取出了 50,只剩下一个 int 的空间。但是,这并不能解释为什么 counters_add 根本没有被调用。 @grassss 我不知道,应该是,至少从您发布的代码部分来看。请阅读minimal reproducible example。【参考方案2】:我注意到newkey
只分配了sizeof(int)
,而您似乎将 50 个字节复制到 newkey。
int *newkey = (int*)malloc(sizeof(int));
newkey = (int*) memcpy(newkey, key, (50 * sizeof(char)));
【讨论】:
以上是关于Int 指针不为空,可以打印,但不能在不引发分段错误的情况下传递给函数的主要内容,如果未能解决你的问题,请参考以下文章
spring bean注入报空指针null,但set设值时对象是存在的,而且只是部分方法报空指针