这是我想要创建的C程序,它监视一组动态分配的结构(在程序初始化时创建)。结构现在具有裸骨要求(fd)。
有效地,
问题在于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
我不知道,是什么导致了这个...是我的malloc还是我执行arithmitic的方式?
valgrind --tool=memcheck --leak-check=yes ./test
==27353== Memcheck, a memory error detector
==27353== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==27353== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==27353== Command: ./test
==27353==
initial address: (nil)
initial address: 0xffefffdc8
Init datahandler memory heap
Completed datahandler memory heap
init address: 0x5202040
init address: 0xffefffdc8
a 0x5202040 0xffefffd78
0x5202040 0xffefffd40
found: 0
inserted: 0
a 0x5202040 0xffefffd78
0x5202040 0xffefffd40
found: 1
inserted: 1
a 0x5202040 0xffefffd78
0x5202040 0xffefffd40
==27353== Invalid write of size 4
==27353== at 0x400784: new_datahub_commhandler_element (test.c:119)
==27353== by 0x4006E9: build_insert_element (test.c:80)
==27353== by 0x400968: main (test.c:213)
==27353== Address 0x5202060 is 0 bytes after a block of size 32 alloc'd
==27353== at 0x4C2BBCF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27353== by 0x400656: init_datahub_commhandler (test.c:49)
==27353== by 0x4008D3: main (test.c:197)
==27353==
==27353== Invalid read of size 4
==27353== at 0x400984: main (test.c:216)
==27353== Address 0x5202060 is 0 bytes after a block of size 32 alloc'd
==27353== at 0x4C2BBCF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27353== by 0x400656: init_datahub_commhandler (test.c:49)
==27353== by 0x4008D3: main (test.c:197)
==27353==
found: 2
==27353== Invalid read of size 4
==27353== at 0x40099B: main (test.c:219)
==27353== Address 0x5202060 is 0 bytes after a block of size 32 alloc'd
==27353== at 0x4C2BBCF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27353== by 0x400656: init_datahub_commhandler (test.c:49)
==27353== by 0x4008D3: main (test.c:197)
==27353==
inserted: 2
a 0x5202040 0xffefffd78
0x5202040 0xffefffd40
found: 3
inserted: 3
a 0x5202040 0xffefffd78
0x5202040 0xffefffd40
found: 4
inserted: 4
a 0x5202040 0xffefffd78
0x5202040 0xffefffd40
found: 5
inserted: 5
a 0x5202040 0xffefffd78
0x5202040 0xffefffd40
found: 6
inserted: 6
a 0x5202040 0xffefffd78
0x5202040 0xffefffd40
found: 7
inserted: 7
==27353== Invalid read of size 4
==27353== at 0x4007EA: search_datahub_commhandler_element (test.c:142)
==27353== by 0x4009CC: main (test.c:222)
==27353== Address 0x5202060 is 0 bytes after a block of size 32 alloc'd
==27353== at 0x4C2BBCF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27353== by 0x400656: init_datahub_commhandler (test.c:49)
==27353== by 0x4008D3: main (test.c:197)
==27353==
valgrind: m_mallocfree.c:303 (get_bszB_as_is): Assertion 'bszB_lo == bszB_hi' failed.
valgrind: Heap block lo/hi size mismatch: lo = 4, hi = 17179869184.
This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata. If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away. Please try that before reporting this as a bug.
host stacktrace:
==27353== at 0x38083F98: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==27353== by 0x380840B4: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==27353== by 0x38084241: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==27353== by 0x38091AEC: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==27353== by 0x3807D653: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==27353== by 0x3807BEE3: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==27353== by 0x380800BA: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==27353== by 0x3807B47A: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==27353== by 0x380593E1: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==27353== by 0x802D490EB: ???
==27353== by 0x802CA9F2F: ???
==27353== by 0x80200831F: ???
==27353== by 0x4009CC: main (test.c:222)
sched status:
running_tid=1
Thread 1: status = VgTs_Runnable (lwpid 27353)
==27353== at 0x4009DC: main (test.c:223)
Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there's a good chance
that fixing those problems will prevent Valgrind aborting or
crashing, especially if it happened in m_mallocfree.c.
If that doesn't help, please report this bug to: www.valgrind.org
In the bug report, send all the above text, the valgrind
version, and what OS and version you are using. Thanks.
任何帮助都会很棒!我在键盘上砸了一下......看起来很有效。给出这个输出
./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
答案 0 :(得分:0)
以下是我最简单的解决方案的代码,这里有一些史诗评论。
#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);
}