sizeof(structname) is this wrong? - c

Windows has triggered a breakpoint in Graph.exe.
This may be due to a corruption of the heap, which indicates a bug in Graph.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while Graph.exe has focus.
The output window may have more diagnostic information
I don't have any breakpoint in my code and I don't pressed F12.
this is my code.
what's wrong?
printf("sizeof edge : %d\n",sizeof(edge));this line make that error.
I can't understand why
what's wrong?
#include <stdio.h>
#include <stdlib.h>
typedef struct HeapStruct heap;
typedef struct edge edge;
struct edge
{
int start,end,weight;
};
struct HeapStruct {
int Capacity;
int Size;
edge *head;
};
void init(int * sets,int size);
int unionsets(int * sets, int i, int j);
int find(int * sets, int i);
void buildHeap(heap h);
edge deleteMin(heap * h);
int ends(int * sets,int size);
int main()
{
int V,E,*sets,a,startv,endv,weight;
char c,h;
edge ed;
edge * ee;
heap * Heap;
Heap = (heap*)malloc(sizeof(heap));
printf("sizeof edge : %d\n",sizeof(edge));//this line
scanf("%d",&V);
sets = (int*)malloc(sizeof(int)*V);
init(sets,V);
scanf("%d",&E);
Heap->head = (edge*)malloc(sizeof(edge)*E);//and this line
Heap->Capacity = E;
Heap->Size=0;
for(a=0; a<E; a++)
{
scanf("%d%c%d%c%d",&startv,&c,&endv,&h,&weight);
Heap->head[Heap->Size].end = endv;
Heap->head[Heap->Size++].start = startv;
Heap->head[Heap->Size++].weight = weight;
}
buildHeap(*Heap);
do
{
ed = deleteMin(Heap);
if(find(sets,ed.start)<0 || find(sets,ed.end)<0 || find(sets,ed.start) != find(sets,ed.end))
{
unionsets(sets,ed.start,ed.end);
printf("%d,%d,%d\n",ed.start,ed.end,ed.weight);
}
}
while(ends(sets,V));
scanf("%d%c%d%c%d",&startv,&c,&endv,&h,&weight);
return 0;
}

Windows has triggered a breakpoint in Graph.exe.
It is literally what it says, the operating system itself made the debugger stop. When you debug your program on any recent Windows version then you get the debug version of the Windows memory manager. Which adds extra checks that ensure that your program isn't corrupting the heap. When it detects heap damage then it breaks the program to tell you about it.
Very useful. What you need to do next is to carefully review your code to make sure it isn't writing to memory that wasn't allocated. You'll then land on this statement:
Heap->head[Heap->Size++].start = startv;
Which along with the other statements in that code assumes that this array contains 3 * E elements but you allocated only E elements.
Kaboom!

printf("sizeof edge : %d\n",sizeof(edge));
This can crash a 64-bit system, because sizeof returns a 64-bit number but %d expects only 32 bits. Try %zd instead.
Yep, C is finicky. Your compiler should have given a warning about this, though.

Related

Lock Free stack implementation idea - currently broken

I came up with an idea I am trying to implement for a lock free stack that does not rely on reference counting to resolve the ABA problem, and also handles memory reclamation properly. It is similar in concept to RCU, and relies on two features: marking a list entry as removed, and tracking readers traversing the list. The former is simple, it just uses the LSB of the pointer. The latter is my "clever" attempt at an approach to implementing an unbounded lock free stack.
Basically, when any thread attempts to traverse the list, one atomic counter (list.entries) is incremented. When the traversal is complete, a second counter (list.exits) is incremented.
Node allocation is handled by push, and deallocation is handled by pop.
The push and pop operations are fairly similar to the naive lock-free stack implementation, but the nodes marked for removal must be traversed to arrive at a non-marked entry. Push basically is therefore much like a linked list insertion.
The pop operation similarly traverses the list, but it uses atomic_fetch_or to mark the nodes as removed while traversing, until it reaches a non-marked node.
After traversing the list of 0 or more marked nodes, a thread that is popping will attempt to CAS the head of the stack. At least one thread concurrently popping will succeed, and after this point all readers entering the stack will no longer see the formerly marked nodes.
The thread that successfully updates the list then loads the atomic list.entries, and basically spin-loads atomic.exits until that counter finally exceeds list.entries. This should imply that all readers of the "old" version of the list have completed. The thread then simply frees the the list of marked nodes that it swapped off the top of the list.
So the implications from the pop operation should be (I think) that there can be no ABA problem because the nodes that are freed are not returned to the usable pool of pointers until all concurrent readers using them have completed, and obviously the memory reclamation issue is handled as well, for the same reason.
So anyhow, that is theory, but I'm still scratching my head on the implementation, because it is currently not working (in the multithreaded case). It seems like I am getting some write after free issues among other things, but I'm having trouble spotting the issue, or maybe my assumptions are flawed and it just won't work.
Any insights would be greatly appreciated, both on the concept, and on approaches to debugging the code.
Here is my current (broken) code (compile with gcc -D_GNU_SOURCE -std=c11 -Wall -O0 -g -pthread -o list list.c):
#include <pthread.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <stdio.h>
#include <unistd.h>
#define NUM_THREADS 8
#define NUM_OPS (1024 * 1024)
typedef uint64_t list_data_t;
typedef struct list_node_t {
struct list_node_t * _Atomic next;
list_data_t data;
} list_node_t;
typedef struct {
list_node_t * _Atomic head;
int64_t _Atomic size;
uint64_t _Atomic entries;
uint64_t _Atomic exits;
} list_t;
enum {
NODE_IDLE = (0x0),
NODE_REMOVED = (0x1 << 0),
NODE_FREED = (0x1 << 1),
NODE_FLAGS = (0x3),
};
static __thread struct {
uint64_t add_count;
uint64_t remove_count;
uint64_t added;
uint64_t removed;
uint64_t mallocd;
uint64_t freed;
} stats;
#define NODE_IS_SET(p, f) (((uintptr_t)p & f) == f)
#define NODE_SET_FLAG(p, f) ((void *)((uintptr_t)p | f))
#define NODE_CLR_FLAG(p, f) ((void *)((uintptr_t)p & ~f))
#define NODE_POINTER(p) ((void *)((uintptr_t)p & ~NODE_FLAGS))
list_node_t * list_node_new(list_data_t data)
{
list_node_t * new = malloc(sizeof(*new));
new->data = data;
stats.mallocd++;
return new;
}
void list_node_free(list_node_t * node)
{
free(node);
stats.freed++;
}
static void list_add(list_t * list, list_data_t data)
{
atomic_fetch_add_explicit(&list->entries, 1, memory_order_seq_cst);
list_node_t * new = list_node_new(data);
list_node_t * _Atomic * next = &list->head;
list_node_t * current = atomic_load_explicit(next, memory_order_seq_cst);
do
{
stats.add_count++;
while ((NODE_POINTER(current) != NULL) &&
NODE_IS_SET(current, NODE_REMOVED))
{
stats.add_count++;
current = NODE_POINTER(current);
next = &current->next;
current = atomic_load_explicit(next, memory_order_seq_cst);
}
atomic_store_explicit(&new->next, current, memory_order_seq_cst);
}
while(!atomic_compare_exchange_weak_explicit(
next, &current, new,
memory_order_seq_cst, memory_order_seq_cst));
atomic_fetch_add_explicit(&list->exits, 1, memory_order_seq_cst);
atomic_fetch_add_explicit(&list->size, 1, memory_order_seq_cst);
stats.added++;
}
static bool list_remove(list_t * list, list_data_t * pData)
{
uint64_t entries = atomic_fetch_add_explicit(
&list->entries, 1, memory_order_seq_cst);
list_node_t * start = atomic_fetch_or_explicit(
&list->head, NODE_REMOVED, memory_order_seq_cst);
list_node_t * current = start;
stats.remove_count++;
while ((NODE_POINTER(current) != NULL) &&
NODE_IS_SET(current, NODE_REMOVED))
{
stats.remove_count++;
current = NODE_POINTER(current);
current = atomic_fetch_or_explicit(&current->next,
NODE_REMOVED, memory_order_seq_cst);
}
uint64_t exits = atomic_fetch_add_explicit(
&list->exits, 1, memory_order_seq_cst) + 1;
bool result = false;
current = NODE_POINTER(current);
if (current != NULL)
{
result = true;
*pData = current->data;
current = atomic_load_explicit(
&current->next, memory_order_seq_cst);
atomic_fetch_add_explicit(&list->size,
-1, memory_order_seq_cst);
stats.removed++;
}
start = NODE_SET_FLAG(start, NODE_REMOVED);
if (atomic_compare_exchange_strong_explicit(
&list->head, &start, current,
memory_order_seq_cst, memory_order_seq_cst))
{
entries = atomic_load_explicit(&list->entries, memory_order_seq_cst);
while ((int64_t)(entries - exits) > 0)
{
pthread_yield();
exits = atomic_load_explicit(&list->exits, memory_order_seq_cst);
}
list_node_t * end = NODE_POINTER(current);
list_node_t * current = NODE_POINTER(start);
while (current != end)
{
list_node_t * tmp = current;
current = atomic_load_explicit(&current->next, memory_order_seq_cst);
list_node_free(tmp);
current = NODE_POINTER(current);
}
}
return result;
}
static list_t list;
pthread_mutex_t ioLock = PTHREAD_MUTEX_INITIALIZER;
void * thread_entry(void * arg)
{
sleep(2);
int id = *(int *)arg;
for (int i = 0; i < NUM_OPS; i++)
{
bool insert = random() % 2;
if (insert)
{
list_add(&list, i);
}
else
{
list_data_t data;
list_remove(&list, &data);
}
}
struct rusage u;
getrusage(RUSAGE_THREAD, &u);
pthread_mutex_lock(&ioLock);
printf("Thread %d stats:\n", id);
printf("\tadded = %lu\n", stats.added);
printf("\tremoved = %lu\n", stats.removed);
printf("\ttotal added = %ld\n", (int64_t)(stats.added - stats.removed));
printf("\tadded count = %lu\n", stats.add_count);
printf("\tremoved count = %lu\n", stats.remove_count);
printf("\tadd average = %f\n", (float)stats.add_count / stats.added);
printf("\tremove average = %f\n", (float)stats.remove_count / stats.removed);
printf("\tmallocd = %lu\n", stats.mallocd);
printf("\tfreed = %lu\n", stats.freed);
printf("\ttotal mallocd = %ld\n", (int64_t)(stats.mallocd - stats.freed));
printf("\tutime = %f\n", u.ru_utime.tv_sec
+ u.ru_utime.tv_usec / 1000000.0f);
printf("\tstime = %f\n", u.ru_stime.tv_sec
+ u.ru_stime.tv_usec / 1000000.0f);
pthread_mutex_unlock(&ioLock);
return NULL;
}
int main(int argc, char ** argv)
{
struct {
pthread_t thread;
int id;
}
threads[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++)
{
threads[i].id = i;
pthread_create(&threads[i].thread, NULL, thread_entry, &threads[i].id);
}
for (int i = 0; i < NUM_THREADS; i++)
{
pthread_join(threads[i].thread, NULL);
}
printf("Size = %ld\n", atomic_load(&list.size));
uint32_t count = 0;
list_data_t data;
while(list_remove(&list, &data))
{
count++;
}
printf("Removed %u\n", count);
}
You mention you are trying to solve the ABA problem, but the description and code is actually an attempt to solve a harder problem: the memory reclamation problem.
This problem typically arises in the "deletion" functionality of lock-free collections implemented in languages without garbage collection. The core issue is that a thread removing a node from a shared structure often doesn't know when it is safe to free the removed node as because other reads may still have a reference to it. Solving this problem often, as a side effect, also solves the ABA problem: which is specifically about a CAS operation succeeding even though the underlying pointer (and state of the object) has been been changed at least twice in the meantime, ending up with the original value but presenting a totally different state.
The ABA problem is easier in the sense that there are several straightforward solutions to the ABA problem specifically that don't lead to a solution to the "memory reclamation" problem. It is also easier in the sense that hardware that can detect the modification of the location, e.g., with LL/SC or transactional memory primitives, might not exhibit the problem at all.
So that said, you are hunting for a solution to the memory reclamation problem, and it will also avoid the ABA problem.
The core of your issue is this statement:
The thread that successfully updates the list then loads the atomic
list.entries, and basically spin-loads atomic.exits until that counter
finally exceeds list.entries. This should imply that all readers of
the "old" version of the list have completed. The thread then simply
frees the the list of marked nodes that it swapped off the top of the
list.
This logic doesn't hold. Waiting for list.exits (you say atomic.exits but I think it's a typo as you only talk about list.exits elsewhere) to be greater than list.entries only tells you there have now been more total exits than there were entries at the point the mutating thread captured the entry count. However, these exits may have been generated by new readers coming and going: it doesn't at all imply that all the old readers have finished as you claim!
Here's a simple example. First a writing thread T1 and a reading thread T2 access the list around the same time, so list.entries is 2 and list.exits is 0. The writing thread pops an node, and saves the current value (2) of list.entries and waits for lists.exits to be greater than 2. Now three more reading threads, T3, T4, T5 arrive and do a quick read of the list and leave. Now lists.exits is 3, and your condition is met and T1 frees the node. T2 hasn't gone anywhere though and blows up since it is reading a freed node!
The basic idea you have can work, but your two counter approach in particular definitely doesn't work.
This is a well-studied problem, so you don't have to invent your own algorithm (see the link above), or even write your own code since things like librcu and concurrencykit already exist.
For Educational Purposes
If you wanted to make this work for educational purposes though, one approach would be to use ensure that threads coming in after a modification have started use a different set of list.entry/exit counters. One way to do this would be a generation counter, and when the writer wants to modify the list, it increments the generation counter, which causes new readers to switch to a different set of list.entry/exit counters.
Now the writer just has to wait for list.entry[old] == list.exists[old], which means all the old readers have left. You could also just get away with a single counter per generation: you don't really two entry/exit counters (although it might help reduce contention).
Of course, you know have a new problem of managing this list of separate counters per generation... which kind of looks like the original problem of building a lock-free list! This problem is a bit easier though because you might put some reasonable bound on the number of generations "in flight" and just allocate them all up-front, or you might implement a limited type of lock-free list that is easier to reason about because additions and deletions only occur at the head or tail.

Detecting stack overflows during runtime beforehand

I have a rather huge recursive function (also, I write in C), and while I have no doubt that the scenario where stack overflow happens is extremely unlikely, it is still possible. What I wonder is whether you can detect if stack is going to get overflown within a few iterations, so you can do an emergency stop without crashing the program.
In the C programming language itself, that is not possible. In general, you can't know easily that you ran out of stack before running out. I recommend you to instead place a configurable hard limit on the recursion depth in your implementation, so you can simply abort when the depth is exceeded. You could also rewrite your algorithm to use an auxillary data structure instead of using the stack through recursion, this gives you greater flexibility to detect an out-of-memory condition; malloc() tells you when it fails.
However, you can get something similar with a procedure like this on UNIX-like systems:
Use setrlimit to set a soft stack limit lower than the hard stack limit
Establish signal handlers for both SIGSEGV and SIGBUS to get notified of stack overflows. Some operating systems produce SIGSEGV for these, others SIGBUS.
If you get such a signal and determine that it comes from a stack overflow, raise the soft stack limit with setrlimit and set a global variable to identify that this occured. Make the variable volatile so the optimizer doesn't foil your plains.
In your code, at each recursion step, check if this variable is set. If it is, abort.
This may not work everywhere and required platform specific code to find out that the signal came from a stack overflow. Not all systems (notably, early 68000 systems) can continue normal processing after getting a SIGSEGV or SIGBUS.
A similar approach was used by the Bourne shell for memory allocation.
Heres a simple solution that works for win-32. Actually resembles what Wossname already posted but less icky :)
unsigned int get_stack_address( void )
{
unsigned int r = 0;
__asm mov dword ptr [r], esp;
return r;
}
void rec( int x, const unsigned int begin_address )
{
// here just put 100 000 bytes of memory
if ( begin_address - get_stack_address() > 100000 )
{
//std::cout << "Recursion level " << x << " stack too high" << std::endl;
return;
}
rec( x + 1, begin_address );
}
int main( void )
{
int x = 0;
rec(x,get_stack_address());
}
Here's a naive method, but it's a bit icky...
When you enter the function for the first time you could store the address of one of your variables declared in that function. Store that value outside your function (e.g. in a global). In subsequent calls compare the current address of that variable with the cached copy. The deeper you recurse the further apart these two values will be.
This will most likely cause compiler warnings (storing addresses of temporary variables) but it does have the benefit of giving you a fairly accurate way of knowing exactly how much stack you're using.
Can't say I really recommend this but it would work.
#include <stdio.h>
char* start = NULL;
void recurse()
{
char marker = '#';
if(start == NULL)
start = &marker;
printf("depth: %d\n", abs(&marker - start));
if(abs(&marker - start) < 1000)
recurse();
else
start = NULL;
}
int main()
{
recurse();
return 0;
}
An alternative method is to learn the stack limit at the start of the program, and each time in your recursive function to check whether this limit has been approached (within some safety margin, say 64 kb). If so, abort; if not, continue.
The stack limit on POSIX systems can be learned by using getrlimit system call.
Example code that is thread-safe: (note: it code assumes that stack grows backwards, as on x86!)
#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
void *stack_limit;
#define SAFETY_MARGIN (64 * 1024) // 64 kb
void recurse(int level)
{
void *stack_top = &stack_top;
if (stack_top <= stack_limit) {
printf("stack limit reached at recursion level %d\n", level);
return;
}
recurse(level + 1);
}
int get_max_stack_size(void)
{
struct rlimit rl;
int ret = getrlimit(RLIMIT_STACK, &rl);
if (ret != 0) {
return 1024 * 1024 * 8; // 8 MB is the default on many platforms
}
printf("max stack size: %d\n", (int)rl.rlim_cur);
return rl.rlim_cur;
}
int main (int argc, char *argv[])
{
int x;
stack_limit = (char *)&x - get_max_stack_size() + SAFETY_MARGIN;
recurse(0);
return 0;
}
Output:
max stack size: 8388608
stack limit reached at recursion level 174549

C: dynamically sized array cannot be accessed in another function

I am working on a connect-four game simulator in C.
https://en.wikipedia.org/wiki/Connect_Four
The first step is to create a board environment for the game. I went ahead and made a data type board_t which is a struct that includes a dynamically sized array that will save moves played in a single dimension array. Board_t also includes height and width information of the board, so things can be retrieved in a correct manner.
I initialize this board in board_create() function, and use this initialized board_t variable in a board_can_play() function to check whether any play is possible in a given play. Here is the code.
#include <stdlib.h>
#include <assert.h>
#define PLAYER_BLUE 2
#define PLAYER_YELLOW 1
#define PLAYER_EMPTY 0
typedef unsigned char player_t;
typedef struct board_t
{
unsigned int width;
unsigned int height;
unsigned int run;
player_t * moves;
} board_t;
bool board_create (board_t ** b, unsigned int height, unsigned int width, unsigned int run, const player_t * i)
{
//Declare a board_t variable temp_b where parameters will be saved.
board_t temp_b;
//Create a pointer and malloc a memory location based on width and height.
temp_b.moves = malloc(sizeof(unsigned char)*(height*width));
//Itereate through the moves and initialize with the given player_t
int j;
for (j = 0; j < width*height; j++)
{
temp_b.moves[j] = PLAYER_EMPTY;
}
//Input all the values to temp_b
temp_b.height = height;
temp_b.width = width;
temp_b.run = run;
//Make a temporary pointer and assign that pointer to *b.
board_t * temp_b_ptr = malloc(sizeof(board_t));
temp_b_ptr = &temp_b;
*b = temp_b_ptr;
return true;
};
/// Return true if the specified player can make a move on the
/// board
bool board_can_play (const board_t * b, player_t p)
{
unsigned int i;
unsigned int height = board_get_height(b);
unsigned int width = board_get_width(b);
for(i = (height-1)*width; i < height*width; i++)
{
if (b->moves[i] == PLAYER_EMPTY)
{
return true;
}
}
return false;
}
However, whenever I call the board_t *b from board_can_play(), the program gives segmentation fault. More specifically,
if (b->moves[i] == PLAYER_EMPTY)
This line is giving me a segmentation fault. Also, functions that worked well in main(), is not working here in board_can_play(). For instance,
unsigned int height = board_get_height(b);
unsigned int width = board_get_width(b);
Are supposed to get 3 and 3, but getting 2 and 419678? I spent about 7 hours now figuring out, but cannot figure out what is going on.
In the if statement that gives you segfault,
if (b->moves[i] == PLAYER_EMPTY)
The problem is not how moves was allocated, but how b itself was allocated. In board_create(), you are returning a temporary object in here:
board_t * temp_b_ptr = malloc(sizeof(board_t));
temp_b_ptr = &temp_b;
*b = temp_b_ptr;
The malloc'ed pointer is lost (you are overwriting it) and simply returning (through *b) a pointer to a local variable.
So the move the allocation to the top and use temp_b_ptr instead of temp_b:
board_t *temp_b_ptr = malloc(sizeof(board_t));
if( !temp_b_ptr ) {
/* error handling */
}
....
....
*b = temp_b_ptr;
I would approach you problem in the following way. Not that I have stubbed-in some error handling, as well as adding a method to destroy the board when done.
The following code compiles without warning in Ubuntu 14.01 LTS, using gcc-4.8.2. I compile the code with the following command line:
gcc -g -std=c99 -pedantic -Wall connect4.c -o connect4
Now, on to the code. You didn't provide a main, so I created a quick stub main:
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <assert.h>
#define PLAYER_BLUE 2
#define PLAYER_YELLOW 1
#define PLAYER_EMPTY 0
typedef unsigned char player_t;
typedef struct board_t
{
unsigned int width;
unsigned int height;
unsigned int run;
player_t * moves;
} board_t;
bool board_create(board_t** b, unsigned int height, unsigned int width);
void board_destroy(board_t** b);
int board_get_height(const board_t* b);
int board_get_width(const board_t* b);
int main(int argc, char** argv)
{
board_t* pBoard = NULL;
if(board_create(&pBoard, 4, 4))
{
printf("board dimensions: %d by %d\n", board_get_height(pBoard), board_get_width(pBoard));
// TODO : put game logic here...
board_destroy(&pBoard);
}
else
{
fprintf(stderr, "failed to initialize the board structure\n");
}
return 0;
}
Not a lot to see in main, much like you would expect. Next is the board_create
function. Note that I deleted the run and the player_t parameters because i didn't see you use them in your code.
bool board_create(board_t** b, unsigned int height, unsigned int width)
{
bool bRet = false;
if(*b != NULL) // we already have a board struct laying about
{
board_destroy(b);
}
if(NULL != (*b = malloc(sizeof(board_t))))
{
(*b)->width = width;
(*b)->height = height;
if(NULL != ((*b)->moves = malloc(sizeof(unsigned char*)*(height * width))))
{
for(int j = 0; j < height * width; j++)
(*b)->moves[j] = PLAYER_EMPTY;
bRet = true;
}
else
{
/* TODO : handle allocation error of moves array */
}
}
else
{
/* TODO : handle allocation error of board struct */
}
return bRet;
}
Couple of comments on this function;
First a bit of defensive programming, I check to see that the board structure has not be previous allocated. If it was I proceed to destroy the previous board prior to creating a new one. This prevent us leaking memory in that is there was a board allocated and then we recalled this function we would over write the pointer to the original board, and this would mean that we would lose our 'handle' to the first board.
Notice that every call to malloc is check to make sure that we actually got the memory that we wanted. I tend to place the check in the same statement as the malloc, but that is personal preference.
I now actually have a significant return value. In you original code, you would just return true regardless if all the allocations succeeded or not. Notice, that I only return true after both allocations are performed, and they succeeded.
Ok, on the the new function I added, board_destroy:
void board_destroy(board_t** b)
{
if(*b != NULL) // no board struct, nothing to do..
{
if((*b)->moves != NULL)
{
free((*b)->moves);
}
free(*b);
*b = NULL;
}
}
Some comments on this function;
a bit more defensive programming, I check to make sure we actually have a board structure to get rid of prior to doing any work.
remember that in your board structure, you have a dynamic array, so you need to free that array first. (free-ing the board structure first would mean that you lost your only reference to the moves array, and you would be leaking memory then).
Prior to free-ing the moves array, I again check to see that it exists.
Once the moves array is destroyed, I proceed to destroy the board structure, and set the pointer back to NULL (in case we want to reuse the board pointer in main).
You didn't provide implementation details of board_get_* functions, but from their usage, I suspect that you have them implemented as:
int board_get_height(const board_t* b)
{
return (b->height);
}
int board_get_width(const board_t* b)
{
return (b->width);
}
I didn't do anything with your board_can_more function due to not being sure how you intend to use it.
A quick run of the above code:
******#ubuntu:~/junk$ ./connect4
board dimensions: 4 by 4
******#ubuntu:~/junk$
My personal opinion is that when doing lots of memory allocations, frees in C or C++ you should run your program under valgrind periodically to make sure you are not leaking memory or have other memory related errors. Below is a sample of running this code under valgrind:
*****#ubuntu:~/junk$ valgrind --tool=memcheck --leak-check=full ./connect4
==4265== Memcheck, a memory error detector
==4265== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4265== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==4265== Command: ./connect4
==4265==
board dimensions: 4 by 4
==4265==
==4265== HEAP SUMMARY:
==4265== in use at exit: 0 bytes in 0 blocks
==4265== total heap usage: 2 allocs, 2 frees, 152 bytes allocated
==4265==
==4265== All heap blocks were freed -- no leaks are possible
==4265==
==4265== For counts of detected and suppressed errors, rerun with: -v
==4265== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Hope this helps,
T.

Problems with structures with pointers to arrays of other structures in C

I am attempting to tackle college worksheet on C programming (no marking for it, just to improve our learning). What we're meant to do is get a few details about shipping docks. I decided to use structures for this.
My code is below, what I need help with is to print out the information (to see if its working) of whats at the location of the shipyards .run.
Everything compiles and according to the debugger shipyard1.run and shipyard2.run point to different locations, but I can not see the values.
int main(int argc, char** argv)
{
typedef struct dockInfo
{
int dockCode;
int dockLength;
}dckDetails;
typdef struct shipyard
{
char dockName[20];
/* however big this number is thats how many dockInfo structs are needed.*/
int numOfDocks;
dckDetails *run; //points to the array of dockInfo structs
};
struct dockInfo *arrayD; // the array to hold all the dockInfo structs
struct dockInfo tempo; // the temporary dockInfo struct to take in the details
struct shipyard shipyard1;
struct shipyard shipyard2;
/**
* the variables for shipyard1 and shipyard2 are then assigned
**/
int i;
for (i=0;i<shipyard1.numOfDocks;i++)
{
arrayD=calloc(shipyard1.numOfDocks,100); // allocate a new bit of memory for arrayD
tempo.dockCode=45*i;
tempo.dockLength=668*i;
arrayD[i]=tempo; //the element of arrayD becomes tempo.
}
shipyard1.run=arrayD; //make shipyard1.run point to the location of arrayD.
for (i=0;i<shipyard2.numOfDocks;i++)
{
arrayD=calloc(shipyard2.numOfDocks,100); // allocate a new bit of memory for arrayD
tempo.dockCode=1234*i;
tempo.dockLength=1200*i;
arrayD[i]=tempo; //the element of arrayD becomes tempo.
}
shipyard2.run=arrayD; //make shipyard2.run point to the new location of arrayD.
int elementTest1; // need element1test to be shipyard1.run[0].dockLength;
int elementTest2; // need element2test to be shipyard2.run[1].dockCode;
return (EXIT_SUCCESS);
}
It should be noted that I have left a lot of code out because I have yet to write it. I have used static examples for the moment (shipyard1 and shipyard2) but in the future I am going to implment a 'load info from file' feature.
Any help would be greatly appreciated and please excuse my English if it's poor, English is not my first language.
You have calloc() inside a for loop twice. Both times you're losing the address returned.
for () {
addr = calloc();
addr[i] = ...
}
the second time through the loop, the addr you got on the first time is gone (you got yourself a memory leak), the value you saved there is gone too.
Move the calloc() outside the loop ... and remember to free() the memory when you no longer need it
addr = calloc();
for () {
addr[i] = ...
}
free(addr);
Some feedback:
The memory allocation parts with calloc should occur outside the loop. Now you allocate it, and then loose track of it in the next iteration because new memory is allocated and assigned.
memory you allocate should be freed somewhere with free
shipyard1.numOfDocks (same for shipyard2) is unitialized when you use it, it may be a random number (which means you have an undefined number of loop iterations, and allocate an undefined amount of memory).
Good luck!
Others have made some very good points, and you should fix your code according to them. So far, no one seems to have seen that the call to calloc() is wrong. Instead of:
arrayD=calloc(shipyard1.numOfDocks,100);
it should be:
arrayD = calloc(shipyard1.numOfDocks, sizeof *arrayD);
You want shipyard1.numOfDocks objects, each of size equal to sizeof *arrayD.
In fact, as mentioned below, you don't need to set the memory allocated to all-zeros, so you can replace calloc() by malloc():
arrayD = malloc(shipyard1.numOfDocks * sizeof *arrayD);
(Be sure to #include <stdlib.h>, whether you call calloc() or malloc().)
I have some minor comments about style:
you don't need the typedef. You can write struct dockInfo instead of dckDetails. If you do keep the typedef, you should be consistent, and use the typedef name everywhere. You use struct dockInfo most of the time, and then use dckDetails once. Your usage suggests that you probably weren't comfortable declaring a pointer to the struct. However, struct dockInfo *run is a completely valid declaration.
you don't need the tempo object. You can instead do: arrayD[i].dockCode = 45*i; arrayD[i].dockLength = 668*i;
Unless you're running C99, you can't declare variables after statements in a block. So you should move the declarations for elementTest1 and elementTest2 to the top of main(), with other declarations.
return is a statement, not a function, so the parentheses are not needed.
Since you overwrite the memory allocated immediately, and don't need it to be zero, you can replace calloc() call by a suitable call to malloc().
As I said, these are minor comments. Your main problems lie with the wrong use of calloc, etc.
I shortened the variable names and re-wrote this to do what I think you are interested in. I also added display of the addresses the data is stored in.
Generally, when I try to understand something in the arrays and pointers world, I make the simple case work - an embedded array (my yard1) and then do the pointer thing after that (yard2, yard3)
You'll note each set of data has different start points, two add i for each point, one multiplies by i for each point.
#include <libc.h>
#include <stdlib.h>
#include <stdio.h>
#define MAX_DOCKS 100
int main(int argc, char** argv)
{
struct dock
{
int code;
int length;
};
struct yard
{
char name[20];
int numDocks;
struct dock arDocks[MAX_DOCKS]; //an array of dock structs
};
struct yard_2
{
char name[20];
int numDocks;
struct dock *run; //points to the array of dock structs
};
/* data within main function */
struct dock *arrayD; // pointer to dock structs
struct yard yard1;
struct yard_2 yard2;
struct yard_2 yard3;
int i;
char temp[] = "2 draY";
strcpy( yard2.name, temp ); /* temp is only persistant in main... */
strcpy( yard1.name, "Yard 1");
strcpy( yard3.name, "3 y 3 a 3 r 3 d 3");
yard1.numDocks = MAX_DOCKS; /* or so I guess.. */
yard2.numDocks = MAX_DOCKS; /* or so I guess.. */
yard3.numDocks = MAX_DOCKS; /* or so I guess.. */
/* get some memory, init it to 0 */
arrayD = calloc( yard2.numDocks, sizeof( struct dock ) );
/* connect to the yard2 struct via "run", a pointer to struct dock */
yard2.run = arrayD;
/* without middleman... get more memory, init it to 0 */
yard3.run = calloc( yard3.numDocks, sizeof( struct dock ) );
/* at this point arrayD could be re-used to get another hunk.. */
/* fill in and display data .. */
for (i=0;i<yard1.numDocks;i++)
{
/* This sets all the memory for yard 1... */
yard1.arDocks[i].code = 45 + i;
yard1.arDocks[i].length = 668 + i;
/* so here are some ways to display the data */
printf("%d, %d %x %d %x - ",
i, yard1.arDocks[i].code, &(yard1.arDocks[i].code),
(yard1.arDocks[i].length), &(yard1.arDocks[i].length) );
/* This sets the memory for yard 2... */
yard2.run[i].code = 45 * i;
yard2.run[i].length = 668 * i;
/* Display through a pointer to a calloc'ed array of structs is the
same syntax as the embedded array of structs. The addresses of the
array are completely different - 0xbffff704 vs 0x800000 on my Intel-based iMac... */
printf("%d %x %d %x - ",
yard2.run[i].code, &(yard2.run[i].code),
yard2.run[i].length, &(yard2.run[i].length) );
yard3.run[i].code = 100 + i;
yard3.run[i].length = 2000 + i;
/* see where second calloc got its memory... */
printf("%d %x %d %x\n",
yard3.run[i].code, &(yard3.run[i].code),
yard3.run[i].length, &(yard3.run[i].length) );
}
/* data all filled in, more demos of how to get it back: */
printf( "%s, : 1\n", yard1.name );
printf( "%d, : numOfDocs \n", yard1.numDocks );
printf( "0x%x, : arDocks \n", yard1.arDocks );
int elementTest1 = yard1.arDocks[0].length;
int elementTest2 = yard1.arDocks[1].code;
int elementTest3 = yard2.run[0].length;
int elementTest4 = yard3.run[1].code;
printf( "elementTest1: yard1.arDocks[0].length %d\n", elementTest1 );
printf( "elementTest2: yard1.arDocks[1].code %d\n", elementTest2 );
printf( "elementTest3: yard2.run[0].length %d\n", elementTest3 );
printf( "elementTest4: yard3.run[1].code; %d\n", elementTest4 );
for (i=0; i< yard2.numDocks; i++ ) {
printf("%d %d %d _ ", i, yard2.run[i].length, yard2.run[i].code);
printf(" %d %d \n", yard3.run[i].length, yard3.run[i].code);
}
return (EXIT_SUCCESS);
}
Here's an edited example of the output, compile/build via cc, cmd line a.out:
Macintosh-6:interview Bill4$ cc
dockyard.c Macintosh-6:interview
Bill4$ a.out
0 45 bffff6f8 668 bffff6fc - 0 800000 0 800004 - 100 800400 2000 800404
1 46 bffff700 669 bffff704 - 45 800008 668 80000c - 101 800408 2001 80040c
2 47 bffff708 670 bffff70c - 90 800010 1336 800014 - 102 800410 2002 800414
:
Yard 1, : 1
100, : numOfDocs
0xbffff6f8, : arDocks
elementTest1: yard1.arDocks[0].length 668
elementTest2: yard1.arDocks[1].code 46
elementTest3: yard2.run[0].length 0
elementTest4: yard3.run[1].code; 101
0 0 0 _ 2000 100
1 668 45 _ 2001 101
2 1336 90 _ 2002 102
3 2004 135 _ 2003 103
:
99 66132 4455 _ 2099 199
Macintosh-6:interview Bill4$

Simple C implementation to track memory malloc/free?

programming language: C
platform: ARM
Compiler: ADS 1.2
I need to keep track of simple melloc/free calls in my project. I just need to get very basic idea of how much heap memory is required when the program has allocated all its resources. Therefore, I have provided a wrapper for the malloc/free calls. In these wrappers I need to increment a current memory count when malloc is called and decrement it when free is called. The malloc case is straight forward as I have the size to allocate from the caller. I am wondering how to deal with the free case as I need to store the pointer/size mapping somewhere. This being C, I do not have a standard map to implement this easily.
I am trying to avoid linking in any libraries so would prefer *.c/h implementation.
So I am wondering if there already is a simple implementation one may lead me to. If not, this is motivation to go ahead and implement one.
EDIT: Purely for debugging and this code is not shipped with the product.
EDIT: Initial implementation based on answer from Makis. I would appreciate feedback on this.
EDIT: Reworked implementation
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <limits.h>
static size_t gnCurrentMemory = 0;
static size_t gnPeakMemory = 0;
void *MemAlloc (size_t nSize)
{
void *pMem = malloc(sizeof(size_t) + nSize);
if (pMem)
{
size_t *pSize = (size_t *)pMem;
memcpy(pSize, &nSize, sizeof(nSize));
gnCurrentMemory += nSize;
if (gnCurrentMemory > gnPeakMemory)
{
gnPeakMemory = gnCurrentMemory;
}
printf("PMemAlloc (%#X) - Size (%d), Current (%d), Peak (%d)\n",
pSize + 1, nSize, gnCurrentMemory, gnPeakMemory);
return(pSize + 1);
}
return NULL;
}
void MemFree (void *pMem)
{
if(pMem)
{
size_t *pSize = (size_t *)pMem;
// Get the size
--pSize;
assert(gnCurrentMemory >= *pSize);
printf("PMemFree (%#X) - Size (%d), Current (%d), Peak (%d)\n",
pMem, *pSize, gnCurrentMemory, gnPeakMemory);
gnCurrentMemory -= *pSize;
free(pSize);
}
}
#define BUFFERSIZE (1024*1024)
typedef struct
{
bool flag;
int buffer[BUFFERSIZE];
bool bools[BUFFERSIZE];
} sample_buffer;
typedef struct
{
unsigned int whichbuffer;
char ch;
} buffer_info;
int main(void)
{
unsigned int i;
buffer_info *bufferinfo;
sample_buffer *mybuffer;
char *pCh;
printf("Tesint MemAlloc - MemFree\n");
mybuffer = (sample_buffer *) MemAlloc(sizeof(sample_buffer));
if (mybuffer == NULL)
{
printf("ERROR ALLOCATING mybuffer\n");
return EXIT_FAILURE;
}
bufferinfo = (buffer_info *) MemAlloc(sizeof(buffer_info));
if (bufferinfo == NULL)
{
printf("ERROR ALLOCATING bufferinfo\n");
MemFree(mybuffer);
return EXIT_FAILURE;
}
pCh = (char *)MemAlloc(sizeof(char));
printf("finished malloc\n");
// fill allocated memory with integers and read back some values
for(i = 0; i < BUFFERSIZE; ++i)
{
mybuffer->buffer[i] = i;
mybuffer->bools[i] = true;
bufferinfo->whichbuffer = (unsigned int)(i/100);
}
MemFree(bufferinfo);
MemFree(mybuffer);
if(pCh)
{
MemFree(pCh);
}
return EXIT_SUCCESS;
}
You could allocate a few extra bytes in your wrapper and put either an id (if you want to be able to couple malloc() and free()) or just the size there. Just malloc() that much more memory, store the information at the beginning of your memory block and and move the pointer you return that many bytes forward.
This can, btw, also easily be used for fence pointers/finger-prints and such.
Either you can have access to internal tables used by malloc/free (see this question: Where Do malloc() / free() Store Allocated Sizes and Addresses? for some hints), or you have to manage your own tables in your wrappers.
You could always use valgrind instead of rolling your own implementation. If you don't care about the amount of memory you allocate you could use an even simpler implementation: (I did this really quickly so there could be errors and I realize that it is not the most efficient implementation. The pAllocedStorage should be given an initial size and increase by some factor for a resize etc. but you get the idea.)
EDIT: I missed that this was for ARM, to my knowledge valgrind is not available on ARM so that might not be an option.
static size_t indexAllocedStorage = 0;
static size_t *pAllocedStorage = NULL;
static unsigned int free_calls = 0;
static unsigned long long int total_mem_alloced = 0;
void *
my_malloc(size_t size){
size_t *temp;
void *p = malloc(size);
if(p == NULL){
fprintf(stderr,"my_malloc malloc failed, %s", strerror(errno));
exit(EXIT_FAILURE);
}
total_mem_alloced += size;
temp = (size_t *)realloc(pAllocedStorage, (indexAllocedStorage+1) * sizeof(size_t));
if(temp == NULL){
fprintf(stderr,"my_malloc realloc failed, %s", strerror(errno));
exit(EXIT_FAILURE);
}
pAllocedStorage = temp;
pAllocedStorage[indexAllocedStorage++] = (size_t)p;
return p;
}
void
my_free(void *p){
size_t i;
int found = 0;
for(i = 0; i < indexAllocedStorage; i++){
if(pAllocedStorage[i] == (size_t)p){
pAllocedStorage[i] = (size_t)NULL;
found = 1;
break;
}
}
if(!found){
printf("Free Called on unknown\n");
}
free_calls++;
free(p);
}
void
free_check(void) {
size_t i;
printf("checking freed memeory\n");
for(i = 0; i < indexAllocedStorage; i++){
if(pAllocedStorage[i] != (size_t)NULL){
printf( "Memory leak %X\n", (unsigned int)pAllocedStorage[i]);
free((void *)pAllocedStorage[i]);
}
}
free(pAllocedStorage);
pAllocedStorage = NULL;
}
I would use rmalloc. It is a simple library (actually it is only two files) to debug memory usage, but it also has support for statistics. Since you already wrapper functions it should be very easy to use rmalloc for it. Keep in mind that you also need to replace strdup, etc.
Your program may also need to intercept realloc(), calloc(), getcwd() (as it may allocate memory when buffer is NULL in some implementations) and maybe strdup() or a similar function, if it is supported by your compiler
If you are running on x86 you could just run your binary under valgrind and it would gather all this information for you, using the standard implementation of malloc and free. Simple.
I've been trying out some of the same techniques mentioned on this page and wound up here from a google search. I know this question is old, but wanted to add for the record...
1) Does your operating system not provide any tools to see how much heap memory is in use in a running process? I see you're talking about ARM, so this may well be the case. In most full-featured OSes, this is just a matter of using a cmd-line tool to see the heap size.
2) If available in your libc, sbrk(0) on most platforms will tell you the end address of your data segment. If you have it, all you need to do is store that address at the start of your program (say, startBrk=sbrk(0)), then at any time your allocated size is sbrk(0) - startBrk.
3) If shared objects can be used, you're dynamically linking to your libc, and your OS's runtime loader has something like an LD_PRELOAD environment variable, you might find it more useful to build your own shared object that defines the actual libc functions with the same symbols (malloc(), not MemAlloc()), then have the loader load your lib first and "interpose" the libc functions. You can further obtain the addresses of the actual libc functions with dlsym() and the RTLD_NEXT flag so you can do what you are doing above without having to recompile all your code to use your malloc/free wrappers. It is then just a runtime decision when you start your program (or any program that fits the description in the first sentence) where you set an environment variable like LD_PRELOAD=mymemdebug.so and then run it. (google for shared object interposition.. it's a great technique and one used by many debuggers/profilers)

Resources