C Valgrind stacktrace失败,结构的线性malloc阵列
这是我想要创建的一个C程序,它监视一组动态分配的结构(在程序初始化时创建)。这些结构具有目前的裸骨要求(fd) 实际上C Valgrind stacktrace失败,结构的线性malloc阵列,c,memory,data-structures,valgrind,C,Memory,Data Structures,Valgrind,这是我想要创建的一个C程序,它监视一组动态分配的结构(在程序初始化时创建)。这些结构具有目前的裸骨要求(fd) 实际上 它初始化N个结构的内存 填写 在其中搜索匹配的文件描述符 在适当的地方进行匹配,如果数量过多,则进行循环 问题在于valgrind。。。我不知道我的指针、结构等有什么不对 代码如下: #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <unistd.h
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>
#include <ctype.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#define NO_ERROR 0
#define DEFAULT_ERROR -1
typedef struct dev_conn_state_s {
int fd;
} dev_con_state_t;
int current_elements = 0;
int max_elements = 0;
int init_datastruct_commhandler(int size, dev_con_state_t ** conn_list);
dev_con_state_t *new_datastruct_commhandler_element(int fd, dev_con_state_t * conn_list);
dev_con_state_t *search_datastruct_commhandler_element(int fd, dev_con_state_t * conn_list);
dev_con_state_t *build_insert_element(dev_con_state_t * conn_list, int fd);
dev_con_state_t *build_search_element(dev_con_state_t * conn_list, int fd);
void set_max_conns(int max);
extern inline int get_max_conns(void);
/**
* init_datastruct_commhandler(int size, dev_con_state_t ** conn_list)
*
* @brief initializes large heap and buffer for each device to be tracked
* @param size
* @param conn_list
* @return (-1) for error, 0 for success
*/
int init_datastruct_commhandler(int size, dev_con_state_t ** conn_list)
{
printf("Init datahandler memory heap\n");
// Quick param check
if (size <= 0) {
return DEFAULT_ERROR;
}
current_elements = 0;
*conn_list = malloc(sizeof(dev_con_state_t) * size);
// Check if malloc failed
if (*conn_list == NULL) {
printf("stack malloc failed\n");
return DEFAULT_ERROR;
}
memset(*conn_list, 0, sizeof(dev_con_state_t) * size);
printf("Completed datahandler memory heap\n");
return NO_ERROR;
}
/**
* build_insert_element(dev_con_state_t *conn_list, struct sockaddr_rc in_addr)
* @brief Build a static element in the heap and insert
* @param conn_list
* @param fd
* @param in_addr
* @param conn if built
*/
dev_con_state_t *build_insert_element(dev_con_state_t * conn_list, int fd)
{
//~ dev_con_state_t conn = { 0 };
//~ printf("ob %p\n",fd);
//~ conn.fd = fd;
//conn.last_activity = time(NULL);
printf("a %p %p\n",conn_list,&conn_list);
return new_datastruct_commhandler_element(fd, conn_list);
}
/**
* build_search_element(dev_con_state_t *conn_list)
* @brief Build a static element in the heap and search
* @param conn_list
* @param fd
* @param in_addr
* @param conn if built
*/
dev_con_state_t *build_search_element(dev_con_state_t * conn_list, int fd)
{
return search_datastruct_commhandler_element(fd, conn_list);
}
/**
* new_datastruct_commhandler_element(dev_con_state_t * conn, dev_con_state_t * conn_list)
*
* @brief Adds new datastruct to connection tracker heap
* @param conn
* @param conn_list
* @return (-1) for error, 0 for success
*/
dev_con_state_t *new_datastruct_commhandler_element(int fd, dev_con_state_t * conn_list)
{
//int size = sizeof(dev_con_state_t) * current_elements;
printf("%p %p\n",conn_list,&conn_list);
dev_con_state_t *tmp = conn_list + (sizeof(dev_con_state_t) * current_elements);
int last_elements = current_elements;
if (current_elements == (max_elements)) {
tmp->fd = fd;
current_elements = 0;
} else {
tmp->fd = fd;
current_elements++;
}
return (dev_con_state_t *) conn_list + (sizeof(dev_con_state_t) * last_elements);
}
/**
* search_datastruct_commhandler_element(dev_con_state_t * conn, dev_con_state_t * conn_list)
*
* @brief Searches for datastruct in connection tracker heap
* @note USES FD (file descriptor) for NOW!
* @param conn
* @param conn_list
* @return NULL for error, non-NULL for success (aka the element we were tracking)
*/
dev_con_state_t *search_datastruct_commhandler_element(int fd, dev_con_state_t * conn_list)
{
int i = 0;
dev_con_state_t *tmp = NULL;
for (i = 0; i < get_max_conns(); i++) {
tmp = (conn_list + (sizeof(dev_con_state_t) * i));
if (tmp->fd == fd) {
return ((dev_con_state_t *) conn_list + (sizeof(dev_con_state_t) * i));
}
}
return (NULL);
}
/**
* cleanup_connection_tracker(dev_con_state_t **conn_list)
*
* @brief Cleanup connection tracker function
* @param conn_list
*/
void cleanup_connection_tracker(dev_con_state_t ** conn_list)
{
if (*conn_list != NULL) {
free(*conn_list);
*conn_list = NULL;
}
}
/**
* set_max_conns(int max)
* @brief set max
* @param max
*/
void set_max_conns(int max)
{
max_elements = max;
}
/**
* get_max_conns(void)
* @brief get max
* @return max
*/
inline int get_max_conns(void)
{
return max_elements;
}
//#ifdef CODE_TEST
#define MAX_DEVS 8
int main(int argc, char **argv)
{
int size = MAX_DEVS;
dev_con_state_t *conn_list = NULL;
printf("initial address: %p\n", conn_list);
printf("initial address: %p\n", &conn_list);
set_max_conns(size);
if (init_datastruct_commhandler(size, &conn_list) < 0) {
return (-1);
}
printf("init address: %p\n", conn_list);
printf("init address: %p\n", &conn_list);
dev_con_state_t conn_array[MAX_DEVS] = { 0 };
dev_con_state_t *ptr = NULL;
int i = 0;
for (i = 0; i < get_max_conns(); i++) {
conn_array[i].fd = i;
//~ if ((ptr = new_datastruct_commhandler_element(conn_array[i].fd, conn_list)) == NULL) {
//~ return (-1);
//~ }
/// test will error -> we looped around
if ((ptr = build_insert_element(conn_list, conn_array[i].fd)) == NULL) {
printf("error finding element\n");
} else {
printf("found: %d\n", ptr->fd);
}
printf("inserted: %d\n", ptr->fd);
}
if ((ptr = search_datastruct_commhandler_element(conn_array[5].fd, conn_list)) != NULL) {
printf("found: %d\n", ptr->fd);
} else {
printf("NOT found: %d\n", conn_array[5].fd);
}
if ((ptr = search_datastruct_commhandler_element(conn_array[3].fd, conn_list)) != NULL) {
printf("found: %d\n", ptr->fd);
} else {
printf("NOT found: %d\n", conn_array[3].fd);
}
/// Still visible out here?
//~ dev_con_state_t *ptr2 =(&conn_list + sizeof(dev_con_state_t));
//~ printf("test: %d\n", ptr2->fd);
/// test for searching for last element
if ((ptr = build_search_element(conn_list, conn_array[6].fd)) == NULL) {
printf("error finding element\n");
} else {
printf("found: %d\n", ptr->fd);
}
/// test for finding a number that doesnt exist
if ((ptr = build_search_element(conn_list, 9)) == NULL) {
printf("error finding element\n");
} else {
printf("found: %d\n", ptr->fd);
}
if ((ptr = build_insert_element(conn_list, conn_array[6].fd)) == NULL) {
printf("error finding element\n");
} else {
printf("inserted: %d\n", ptr->fd);
}
/// test will error -> we looped around
if ((ptr = build_search_element(conn_list, conn_array[0].fd)) == NULL) {
printf("error finding element\n");
} else {
printf("found: %d\n", ptr->fd);
}
cleanup_connection_tracker(&conn_list);
printf("Done\n");
return (0);
}
//#endif
任何帮助都将是惊人的!我的头撞在键盘上。。。它似乎起作用了。鉴于此输出
./test
initial address: (nil)
initial address: 0x7fff41386a68
Init datahandler memory heap
Completed datahandler memory heap
init address: 0x650010
init address: 0x7fff41386a68
a 0x650010 0x7fff41386a18
0x650010 0x7fff413869e0
found: 0
inserted: 0
a 0x650010 0x7fff41386a18
0x650010 0x7fff413869e0
found: 1
inserted: 1
a 0x650010 0x7fff41386a18
0x650010 0x7fff413869e0
found: 2
inserted: 2
a 0x650010 0x7fff41386a18
0x650010 0x7fff413869e0
found: 3
inserted: 3
a 0x650010 0x7fff41386a18
0x650010 0x7fff413869e0
found: 4
inserted: 4
a 0x650010 0x7fff41386a18
0x650010 0x7fff413869e0
found: 5
inserted: 5
a 0x650010 0x7fff41386a18
0x650010 0x7fff413869e0
found: 6
inserted: 6
a 0x650010 0x7fff41386a18
0x650010 0x7fff413869e0
found: 7
inserted: 7
found: 5
found: 3
found: 6
error finding element
a 0x650010 0x7fff41386a18
0x650010 0x7fff413869e0
inserted: 6
found: 0
Done
下面是我的最简单解决方案的代码,正如这里一些史诗般的评论所给出的
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
typedef struct mystruct_s {
int fd;
int a;
int b;
} mystruct_t;
int current_elements = 0;
int max_elements = 0;
int init(int size, mystruct_t ** conn_list)
{
if (size <= 0) {
return (-1);
}
current_elements = 0;
*conn_list = malloc(max_elements *sizeof(mystruct_t));
if (*conn_list == NULL) {
return (-1);
}
return (0);
}
void insert(int fd, mystruct_t ** conn_list, mystruct_t ** res)
{
*res = NULL;
if (current_elements == (max_elements)) {
(*conn_list)[current_elements].fd = fd;
(*conn_list)[current_elements].a = fd;
(*conn_list)[current_elements].b = fd;
*res = &(*conn_list)[current_elements];
current_elements = 0;
} else {
(*conn_list)[current_elements].fd = fd;
(*conn_list)[current_elements].a = fd;
(*conn_list)[current_elements].b = fd;
*res = &(*conn_list)[current_elements];
current_elements++;
}
}
int search(int fd, mystruct_t ** conn_list, mystruct_t ** res)
{
int i = 0;
if (*conn_list == NULL) {
*res = NULL;
return (-1);
}
for (i = 0; i < max_elements; i++) {
if ((*conn_list)[i].fd == fd) {
*res = &(*conn_list)[i];
return (1);
}
}
*res = NULL;
return (-1);
}
#define MAX_ELEMENTS 8
int main(int argc, char **argv)
{
int size = MAX_ELEMENTS;
mystruct_t conn_array[MAX_DEVS] = { 0 };
mystruct_t *conn_list = NULL;
max_elements = MAX_DEVS;
if (init(size, &conn_list) < 0) {
return (-1);
}
mystruct_t *ptr = NULL;
int i = 0;
for (i = 0; i < max_elements; i++) {
conn_array[i].fd = i;
insert(conn_array[i].fd, &conn_list, &ptr);
}
if ((search(conn_array[5].fd, &conn_list, &ptr)) > 0) {
printf("Found: %d\n", ptr->fd);
} else {
printf("NOT found: %d\n", conn_array[5].fd);
}
if (conn_list != NULL) {
free(conn_list);
}
return (0);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
typedef struct mystruct_s{
int-fd;
INTA;
int b;
}我的结构;
int当前_元素=0;
int max_元素=0;
int init(int大小,我的结构**连接列表)
{
如果(尺寸0){
printf(“找到:%d\n”,ptr->fd);
}否则{
printf(“未找到:%d\n”,连接数组[5].fd);
}
如果(连接列表!=NULL){
免费(连接列表);
}
返回(0);
}
请构造一个。奥利弗,我更新了它。请阅读如何创建MCVE()。请注意,MCVE必须是自包含的(它生成或包含自己的数据),或者必须指定使用的数据。报告的错误似乎是直截了当的。Valgrind发现您的写作超出了分配结构的末尾。您似乎有:dev\u con\u state\u t*tmp=conn\u list+(sizeof(dev\u con\u state\u t)*当前元素)代码>-为什么要乘以尺寸?C已经根据对象的大小缩放指针算法。你的意思是dev\u con\u state\u t*temp=conn\u list+当前元素代码>,我相信。你好,乔纳森,谢谢你的评论。我想我需要乘法,因为conn_list是内存的一个线性段,仅仅是说,有5个元素只会使ptr增加5个字节……你的指针算法仍然是错误的。不需要乘以元素的大小。为什么要使用指针算法呢?C中的数组有一个非常好的索引操作符conn\u list[i]
是您所需要的一切。@n.m您能告诉我为什么数组会更好吗?在这种情况下,它们不是动态的,可能需要更改。除非您指的是指针数组,“为什么数组会更好”malloc(n*sizeof(mystruct_t))
为类型为mystruct_t
的n
元素数组分配空间,并返回指向其第一个元素的指针。现在您可以选择正确使用或错误使用它<代码>连接列表[i]
将是正确使用的示例。因此应该是*(conn_list+i)
,根据定义,这与前面的示例相当<代码>*(conn_list+i*sizeof(mystruct_t))
是不正确使用的一个例子<代码>连接列表[i]易于阅读和编写。你写的东西既不正确,也不正确。@n.m好极了,我已经更新了。有没有更好的书写方式:(*conn_list)[current_elements].fd=fd;如果conn\u list
是一个dev\u con\u state**
,那么没有更好的方法了。您可以编写conn\u list[0][current\u elements]
,但这并不是一个改进。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
typedef struct mystruct_s {
int fd;
int a;
int b;
} mystruct_t;
int current_elements = 0;
int max_elements = 0;
int init(int size, mystruct_t ** conn_list)
{
if (size <= 0) {
return (-1);
}
current_elements = 0;
*conn_list = malloc(max_elements *sizeof(mystruct_t));
if (*conn_list == NULL) {
return (-1);
}
return (0);
}
void insert(int fd, mystruct_t ** conn_list, mystruct_t ** res)
{
*res = NULL;
if (current_elements == (max_elements)) {
(*conn_list)[current_elements].fd = fd;
(*conn_list)[current_elements].a = fd;
(*conn_list)[current_elements].b = fd;
*res = &(*conn_list)[current_elements];
current_elements = 0;
} else {
(*conn_list)[current_elements].fd = fd;
(*conn_list)[current_elements].a = fd;
(*conn_list)[current_elements].b = fd;
*res = &(*conn_list)[current_elements];
current_elements++;
}
}
int search(int fd, mystruct_t ** conn_list, mystruct_t ** res)
{
int i = 0;
if (*conn_list == NULL) {
*res = NULL;
return (-1);
}
for (i = 0; i < max_elements; i++) {
if ((*conn_list)[i].fd == fd) {
*res = &(*conn_list)[i];
return (1);
}
}
*res = NULL;
return (-1);
}
#define MAX_ELEMENTS 8
int main(int argc, char **argv)
{
int size = MAX_ELEMENTS;
mystruct_t conn_array[MAX_DEVS] = { 0 };
mystruct_t *conn_list = NULL;
max_elements = MAX_DEVS;
if (init(size, &conn_list) < 0) {
return (-1);
}
mystruct_t *ptr = NULL;
int i = 0;
for (i = 0; i < max_elements; i++) {
conn_array[i].fd = i;
insert(conn_array[i].fd, &conn_list, &ptr);
}
if ((search(conn_array[5].fd, &conn_list, &ptr)) > 0) {
printf("Found: %d\n", ptr->fd);
} else {
printf("NOT found: %d\n", conn_array[5].fd);
}
if (conn_list != NULL) {
free(conn_list);
}
return (0);
}