C Valgrind stacktrace失败,结构的线性malloc阵列

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

这是我想要创建的一个C程序,它监视一组动态分配的结构(在程序初始化时创建)。这些结构具有目前的裸骨要求(fd)

实际上

  • 它初始化N个结构的内存
  • 填写
  • 在其中搜索匹配的文件描述符
  • 在适当的地方进行匹配,如果数量过多,则进行循环
  • 问题在于valgrind。。。我不知道我的指针、结构等有什么不对

    代码如下:

    #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);
    }