The code shows the segmentation fault in the function free_nlist()(line#539) within the nlist.c file.
I tried one thing but I do not think that it was logical; I tried allocating the dynamic memory to the variable "nlb_head"(line #542) using the command :
nlb_head = (struct nlblock *) malloc( sizeof( struct nlblock ) );
It did give me the results but can anyone explain as to whether this is correct or not.
void free_nlist( struct nlblock *nlb_head )
{
struct nlblock *nlb_tmp;
nlb_tmp=NULL;
while( nlb_head != NULL )
{
nlb_tmp = nlb_head->next;
free( nlb_head );
nlb_head = nlb_tmp;
}
free(nlb_tmp);
}
The link to the code is given below:
https://drive.google.com/open?id=1BDP-gkSP9rPvAM4oVdNYmwmJqPhy3o_w
Related
I define a struct type as follows:
typedef struct {
int obs_flag;
double obs_timestamp;
int event_mask;
char *event_name;
char *filedir;
} structdata;
where I have a pointer named obs_data:
structdata *obs_data;
then I want to assign each object of the obs_data as follows:
int observer_flag = 1;
double ctime = 2309212380.323100;
struct inotify_event* event = (struct inotify_event*)(buffer + bytesProcessed);
obs_data->obs_flag = observer_flag;
obs_data->obs_timestamp = ctime;
obs_data->event_mask = event->mask;
obs_data->event_name = event->name;
obs_data->filedir = "./myDir/";
in the above, event is a struct from the inotify that captures the events associated with changes to a file or directory in Linux.
when I run the above chunk of code in my program I encounter the Segmentation fault (core dumped).
I am not a pro working with stucts and pointers. Any help is greatly appreciated.
Your obs_data is just a pointer!! It's not an instance of structdata. If you want it to be a pointer, you need to malloc memory to hold the struct.
So before using obs_data you need code like:
obs_data = malloc(sizeof *obs_data); // Allocate memory for 1 instance of structdata
if (obs_data == NULL)
{
// allocation failed
exit(1);
}
// Now you can assign values like
obs_data->obs_flag = observer_flag;
...
...
and once you are done using it, remember to free the memory like
free(obs_data);
I'm working with a kernel module, which is causing a null pointer dereference when inserted. I've tracked the error down to this function in swnode.c (not part of the kernel module, but is called by the module):
static struct fwnode_handle *
software_node_get_next_child(const struct fwnode_handle *fwnode,
struct fwnode_handle *child)
{
struct swnode *p = to_swnode(fwnode);
struct swnode *c = to_swnode(child);
if (!p || list_empty(&p->children) ||
(c && list_is_last(&c->entry, &p->children)))
return NULL;
if (c) {
c = list_next_entry(c, entry);
if (c->node)
pr_info("child node named %s\n", c->node->name);
} else {
c = list_first_entry(&p->children, struct swnode, entry);
}
return fwnode_handle_get(&c->fwnode);
}
I added the pr_info("child node named %s\n", c->node->name); call for debugging, and that line causes the null pointer dereference. Prior to that the error was with return fwnode_handle_get(&c->fwnode) which caused an oops complaining I was executing things in NX memory; it's apparent that c->fwnode is NULL, so I can try to work out why that is, I'm just wondering why my debug print caused an error too.
This situation confuses me; I'm explicitly checking that c and c->node are not null, in a way that I thought should protect against this kind of error (based on answers like this). The dereference operations are against c (because, by my understanding, c->member is equivalent to (*c).member) and c->node. So; why, given the pr_info call should only be evaluated if c and c->node are not null does it cause a null pointer dereference?
EDIT:
Close voters need to read both question and threads more carefully. This issue is not caused by a typo. The missing curly braces in the original example (which has since been edited to include them) are not the cause of the issue.
Your code
if (c)
c = list_next_entry(c, entry);
if (c->node)
pr_info("child node named %s\n", c->node->name);
else
c = list_first_entry(&p->children, struct swnode, entry);
is equivalent to
if (c) {
c = list_next_entry(c, entry);
}
if (c->node) {
pr_info("child node named %s\n", c->node->name);
} else {
c = list_first_entry(&p->children, struct swnode, entry);
}
Therefore, c->node will be evaluated regardless of whether c is NULL.
Add braces to have the check for c work.
if (c) { /* add a brace */
c = list_next_entry(c, entry);
if (c->node)
pr_info("child node named %s\n", c->node->name);
} /* add a brace */
else
c = list_first_entry(&p->children, struct swnode, entry);
I get a pretty weird segmentation fault error when I am trying to use the same function in two different places.
printTVNode function work fine on main.
On Main:
printTVNode(headTVNode); /* Works fine here */
TVNodePointer headTopic = NULL;
TopicEmmissions(&headTopic,headTVNode,desiredTopic);
When I am trying to use printTVNode inside TopicEmmissions function a get Seg Fault.
void TopicEmmissions(TVNodePointer * headTopic,TVNodePointer headTVNode,char * desiredTopic){
TVNodePointer currentTVNode = headTVNode;
EmmissionPointer currentEmmission;
EventPointer currentEvent;
EventPointer topicSubjects = NULL;
int flag,countEvent = 1,countEmmission = 1;
printTVNode(headTVNode); /* Get Segmentation Fault here*/
...
printTVNode function:
void printTVNode(TVNodePointer headTVNode){
TVNodePointer currentTVNode = headTVNode;
while ( currentTVNode != NULL ){
printEmmission(*(currentTVNode->anEmmission));
currentTVNode = currentTVNode->next;
}
}
The problem seems to be in the following line :
printEmmission(*(currentTVNode->anEmmission));
In a situation where anEmmission is NULL, when you try to dereference it, I think you will get a segfault.
Make sure to check that anEmmission is not NULL before doing dereferencing.
I'm using uthash.h in order to store my application's configuration. As the config comes from a file that is read at runtime, the keys and values within the hash are both dynamically allocated char *'s:
typedef struct config_entry {
char *name;
char *value;
UT_hash_handle hh;
} CONFIG_ENTRY;
As explained in the user guide, I implemented my own function to add keys to the config-hash that ensures uniqueness. Here it is:
void cfg_put( char *name, char *value, FREE_FLAGS flags ) {
CONFIG_ENTRY *entry;
//first, check if the key is already in the hash
HASH_FIND_STR( config_, name, entry );
if( entry == NULL ) {
//key doesn't exist yet => create new one
entry = (CONFIG_ENTRY *)malloc( sizeof( CONFIG_ENTRY ) );
entry->name = name;
HASH_ADD_KEYPTR( hh, config_, entry->name, strlen(entry->name), entry );
} else {
//key exists => possibly free existing pointers before setting value
if( (flags & FREE_NAME) == FREE_NAME ) { //
free( entry->name ); // these lines seem to be
} // problematic.
entry->name = name; //
if( (flags & FREE_VALUE) == FREE_VALUE ) {
free( entry->value );
}
}
//Finally, set the value
entry->value = value;
}
I also wrote up some testcases for checking my implementation, and they seem to run just fine. However, if I run the tests using valgrind to check for memleaks, I always get the following:
==2561== Invalid read of size 1
==2561== at 0x4026097: bcmp (mc_replace_strmem.c:541)
==2561== by 0x804ADF5: cfg_get (in /home/gj/..../test/config_test)
==2561== by 0x804B2C7: test_config1 (in /home/..../test/config_test)
==2561== by 0x402E446: run_single_test (in /usr/local/lib/libcunit.so.1.0.1)
[...]
==2561== Address 0x4194210 is 0 bytes inside a block of size 4 free'd
==2561== at 0x4023B6A: free (vg_replace_malloc.c:366)
==2561== by 0x804A872: cfg_put (in /home/..../test/config_test)
==2561== by 0x804B27D: test_config1 (in /home/..../test/config_test)
==2561== by 0x402E446: run_single_test (in /usr/local/lib/libcunit.so.1.0.1)
[...]
Here's the test case and the implementation of cfg_get for completeness:
void test_config1( void ) {
cfg_clear( FREE_ALL );
cfg_put( strdup("foo"), "bar", FREE_NONE );
CU_ASSERT_EQUAL( cfg_count(), 1 );
CU_ASSERT_STRING_EQUAL( cfg_get("foo"), "bar" );
cfg_dump();
cfg_put( "foo", "baz", FREE_NAME );
CU_ASSERT_EQUAL( cfg_count(), 2 );
CU_ASSERT_STRING_EQUAL( cfg_get("foo"), "baz" );
cfg_clear( FREE_NONE );
cfg_dump();
}
cfg_get:
char *cfg_get( const char *name ) {
CONFIG_ENTRY *entry = NULL;
HASH_FIND_STR( config_, name, entry );
if( entry ) {
return entry->value;
} else {
return NULL;
}
}
Somehow, it seems I'm accessing the old name-pointer in cfg_get after I've overwritten it in cfg_put. The problem only occurs for the name, not for the value. I'm too stupid to figure it out, thx for any advice.
You'll have to provide the complete program — that is, a complete minimal example that reproduces the valgrind issue. The code you've posted in your question looks fine, so the bug must be hiding somewhere else; e.g. in the code of cfg_clear() or cfg_count().
(Originally I thought that cfg_count() must be return HASH_COUNT(config_); — but that implementation wouldn't pass your test case, so you must be doing something weirder. Which means cfg_count is probably the wrong name for that function anyway.)
Stylistically, you might find your code easier to debug if you avoided the use of global variables (config_), and definitely you'd find it easier if you stored the "necessity to free this value" bits directly alongside the "value" bits, instead of requiring the user to keep track of FREE_NAME, FREE_VALUE, etc., on his own. That is, instead of
typedef struct config_entry {
char *name;
char *value;
UT_hash_handle hh;
} CONFIG_ENTRY;
void cfg_put(char *name, char *value, FREE_FLAGS flags);
void cfg_clear(FREE_FLAGS flags);
you should provide merely
typedef struct config_entry {
char *name;
char *value;
UT_hash_handle hh;
bool must_free_name;
bool must_free_value;
} CONFIG_ENTRY;
void cfg_put(char *name, char *value, FREE_FLAGS flags);
void cfg_clear(void);
at which point your test case becomes the more manageable
void test_config1()
{
cfg_clear(); // use the stored bits to figure out what needs freeing
cfg_put(strdup("foo"), "bar", FREE_NAME); // name is alloc'ed, so name must be freed later
CU_ASSERT_EQUAL( cfg_count(), 1 );
CU_ASSERT_STRING_EQUAL( cfg_get("foo"), "bar" );
cfg_put("foo", "baz", FREE_NONE); // neither name nor value is alloc'ed
CU_ASSERT_EQUAL( cfg_count(), 2 );
CU_ASSERT_STRING_EQUAL( cfg_get("foo"), "baz" );
}
There is a problem in your config_put() function: it modifies the key of an item already inserted in to the hash. You are not supposed to do this. It may be OK to change the name pointer to one that points to the same string, but it may be not, the implementation of uthash.h is a bit obscure.
I suggest you change the API so config_put() does all the string management, letting the config_ hash own all the strings, and no longer call strdup() in test_config1. This is much simpler and avoids the potentially complicated and error prone tracking of the life cycle of string values outside of the hash structure:
void cfg_put(const char *name, const char *value) {
CONFIG_ENTRY *entry;
//first, check if the key is already in the hash
HASH_FIND_STR(config_, name, entry);
if (entry == NULL) {
//key doesn't exist yet => create new one
entry = malloc(sizeof(*entry));
entry->name = strdup(name);
HASH_ADD_KEYPTR(hh, config_, entry->name, strlen(entry->name), entry );
} else {
//key exists => free existing value pointer if any
free(entry->value);
}
//Finally, set the value
entry->value = value ? strdup(value) : NULL;
}
I'm attempting to write a solver for a particular puzzle. It tries to find a solution by trying every possible move one at a time until it finds a solution. The first version tried to solve it depth-first by continually trying moves until it failed, then backtracking, but this turned out to be too slow. I have rewritten it to be breadth-first using a queue structure, but I'm having problems with memory management.
Here are the relevant parts:
int main(int argc, char *argv[])
{
...
int solved = 0;
do {
solved = solver(queue);
} while (!solved && !pblListIsEmpty(queue));
...
}
int solver(PblList *queue) {
state_t *state = (state_t *) pblListPoll(queue);
if (is_solution(state->pucks)) {
print_solution(state);
return 1;
}
state_t *state_cp;
puck new_location;
for (int p = 0; p < puck_count; p++) {
for (dir i = NORTH; i <= WEST; i++) {
if (!rules(state->pucks, p, i)) continue;
new_location = in_dir(state->pucks, p, i);
if (new_location.x != -1) {
state_cp = (state_t *) malloc(sizeof(state_t));
state_cp->move.from = state->pucks[p];
state_cp->move.direction = i;
state_cp->prev = state;
state_cp->pucks = (puck *) malloc (puck_count * sizeof(puck));
memcpy(state_cp->pucks, state->pucks, puck_count * sizeof(puck)); /*CRASH*/
state_cp->pucks[p] = new_location;
pblListPush(queue, state_cp);
}
}
}
free(state->pucks);
return 0;
}
When I run it I get the error:
ice(90175) malloc: *** mmap(size=2097152) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Bus error
The error happens around iteration 93,000.
From what I can tell, the error message is from malloc failing, and the bus error is from the memcpy after it.
I have a hard time believing that I'm running out of memory, since each game state is only ~400 bytes. Yet that does seem to be what's happening, seeing as the activity monitor reports that it is using 3.99GB before it crashes. I'm using http://www.mission-base.com/peter/source/ for the queue structure (it's a linked list).
Clearly I'm doing something dumb. Any suggestions?
Check the result of malloc. If it's NULL, you might want to print out the length of that queue.
Also, the code snippet you posted didn't include any frees...
You need to free() the memory you've allocated manually after you're done with it; dynamic memory doesn't just "free itself"