Allocating memory to my stack dynamically (only if needed) - c

I need to allocate memory to an array inside my struct, this array has no defined size at the beginning when i define the struct:
typedef struct stacks {
int size; // Stores the size of my -values- array
int sp; //points to the top of the stack, my stackpointer
int *values;
} STACKS;
So, to initialize my struct i wrote this function, that allocates (using calloc?) memory to my array, and i put inside SIZE variable, the new size of my array .
#define MAXIMUM 10
int initStacks(STACKS *s){
s->values = calloc(MAXIMUM,sizeof(int));
s->size = MAXIMUM;
s->sp = 0;
return 0;
}
Now, if i want to push something to the top of the stack (LIFO) i use this:
int pushs(STACKS *s, int x){
if (s->sp==s->size) {
realloc(s->values, MAXIMUM * sizeof(int));
s->size*=2;
}
s->values[s->sp]=x;
s->sp++;
}
Is this the correct way of doing this?
Is realloc working as it should in my function?
Thank you very much for your help!
EDIT:
would this make more sense? This way, i really don't need to declare the value of the array, being that defined with #define maximum 10
typedef struct stacks {
int size; // guarda o tamanho do array valores
int sp;
int *values;
} STACKS;
int initStacks(STACKS *s){
s->values = calloc(1,sizeof(int));
s->size = 1;
s->sp = 0;
return 0;
}
int isEmptys(STACKS *s){
return((s->sp)==0);
}
int pushs(STACKS *s, int x){
s->size++;
realloc(s->values, s->size * sizeof(int));
s->values[s->sp]=x;
s->sp++;
}

Assuming you have an original size factor (the name capacity would be as-appropriate, if not more so), your original code lacks several things:
Compares the size against a constant, rather than the current sp against the stack current size.
Does not save nor test the return result of realloc
Does not actually double the allocation (you're missing the 2x in the realloc expression.
Declares an int return result, but no such return exists.
Has no way of communicating back to the caller the push result (success or not). That missing return result would be ideal for this, btw.
Addressing all of these:
int pushs(STACKS *s, int x)
{
if (s->sp == s->size)
{
void *pv = realloc(s->values, 2 * s->size * sizeof *(s->values));
if (pv != NULL)
{
s->values = pv;
s->size *= 2;
}
else
{
fprintf(stderr, "Failed to resize stack\n");
return -1;
}
}
s->values[s->sp++] = x;
return 0;
}
Untested, but hopefully close enough.
Best of luck

Although not directly an answer to the actual question, but more to the general problem, I post this as it does not fit into a comment.
If you expect excessive push/pop operations and memory usage, the following might be an alternative:
typedef struct SubStack_s {
struct SubStack_s *prev;
int data[ENTRIES_PER_SEGMENT];
} SubStack;
typedef struct {
SubStack *tos; // init to NULL
size_t sp; // init to 0
} Stack;
The basic idea is to push elements onto each substack until full (as you already do). If the current one is full, you alloc a new one, chain them (new->prev = old) and continue with the new one (storing new to Stack.tos)
Pop works similar, free'ing each substack once it is not used anymore.
That concept is called "fragmented stack". It is much more efficient than the realloc-approach (it avoids copying) and does not fragment RAM as all block are of equal size. Oh, and it allows to have pointers into the stack, which the realloc-varaint does not, because the address of the stack can change.

Related

how can i solve this when i try to return a 2d struct from a function

this is how i declare this struct
typedef struct cache{
int vaild;
char* tag;
char* data;
}cache;
this is part of my main which called this function
struct cache **cacheA = createCache(Setnum,(int)pow(2,blocksize),cachesize);
struct cache **cacheB = createCache(Setnum,(int)pow(2,blocksize),cachesize);
and now this is my called function
struct cache ** createCache(int numset, int blocksize, int cachesize){
int numcache = (int)((cachesize/blocksize)*numset);
struct cache out[numset][numcache];
int i,j;
for (i=0; i < numset; i++){
for (j=0; j < numcache; j++){
out[i][j].tag = "0";
out[i][j].vaild = 0;
out[i][j].data ="0";
}
}
return out;
}
and when i try to compile this, it tells me that
return from incompatible pointer type
function returns address of local variable
(which points to the line "return out;")
I have no idea whats wrong with my code, i mean the type of the function return is the same as how i declear "out", so what causes this problem?
You create struct cache out[numset][numcache];
within the function prototyped as: struct cache ** createCache(...).
Then attempt to return out.
It is because struct cache [][] is typed differently than struct cache ** that you are getting the return errors.
Other comments:
1) If you truly do want a pointer to pointer to struct, then malloc or calloc will need to be used at some point to allocate memory.
2) the char * members of the struct also need to be assigned memory before assigning values. For illustration below, they are changed to char []
3) assigning values to strings does not work by using = assignment operator. Use a string function such as strcpy, sprintf, etc.
4) you've named the struct with the same symbol as that of the new type you have created, i.e. cache. In this application, the name cache is not necessary. Also, purely for style, I show the new type in CAPS. This is not necessary, but just a style I use to make the new type more recognizable in code.
In consideration of the comments above, the struct could be changed to the following:
typedef struct { /// don't need name here when it in this application
int vaild;
//char *tag;
char tag[20];//for illustration, to avoid additional dynamic allocation of memory
//char* data;
char data[80];
}CACHE;//capitalization is style only, not a necessity here.
Note, there is no name, but the new type CACHE was created. Now, you can create the function createCache:
CACHE ** createCache(int ncache, int nset)//note for simplicity of freeing this
//object later, simplify number of arguments
{
CACHE **out;
out = calloc(ncache, sizeof(CACHE *));//create array of pointers to CACHE
if(!out) return NULL;
int i;
for (i=0; i < nset; i++)
{
out[i] = calloc(nset, sizeof(CACHE));//create space for each instance
//of CACHE pointed to by array pointers
}
return out;
}
Anytime memory is created on the heap, it needs to be freed. This method will free the CACHE object memory:
void freeCashe(CACHE **a, int nset)
{
int i;
for(i=0; i<nset; i++)
{
if(a[i])free(a[i]);
}
if(a)free(a);
}
Calling these functions as shown below, will create an array of pointers, each pointing to an instance of CACHE where you can use them as intended, then free all of the memory when finished:
int main(void)
{
int cachesize = 20;
int blocksize = 20;
int numset = 10;
//move the calculation out of creation function
//to simplify freeing object later.
int numcache = (int)((cachesize/blocksize)*numset);
CACHE **a = createCache(numcache, numset);
/// use a, then free a
freeCashe(a, numset);
return 0;
}
Your function needs to allocate the memory on the heap rather than the stack. You will need to allocate space on the heap for your array of pointers, and for what they point too.
struct cache ** createCache(int numset, int blocksize, int cachesize){
cache ** out;
int numcache = (int)((cachesize/blocksize)*numset);
size_t headerSize = sizeof(*out)*numset;
size_t bodySize = sizeof(**out)*numcache;
out = malloc(headerSize + (bodySize*numset));
if (out == NULL) {
/* Should probably output some message about being
* insufficient memory here. */
return NULL;
}
int i,j;
for (i=0; i < numset; i++){
/* need to assign our point */
out[i] = (cache*)(((char*)out)+(headerSize+bodySize*i));
for (j=0; j < numcache; j++){
out[i][j].tag = "0";
out[i][j].vaild = 0;
out[i][j].data ="0";
}
}
return out;
}
/* importantly, you want a way to free your allocated memory */
void destroyCache(cache ** ptr) {
free(ptr);
}
PS: You don't have to typedef your struct if you reference it with the struct keyword.
You are wanting a pointer pointer type to be returned, but in order to do that you need to dynamically allocate it. Local stack allocations (i.e. struct cache[x][y]) won't work. You will either get an error or your program will crash when attempting to use the 2D array.
The solution is to either pre-allocate space and pass it in to the function or allocate in the function itself.
Allocation In Function Example:
struct cache ** createCache(int numset, int blocksize, int cachesize){
int numcache = (int)((cachesize/blocksize)*numset);
struct cache **out = malloc(sizeof(struct cache *) * numset); // This line changed.
int i,j;
for (i=0; i < numset; i++){
out[i] = malloc(sizeof(struct cache) * numcache); // This line added.
for (j=0; j < numcache; j++){
out[i][j].tag = malloc(sizeof(char)); // This line added.
out[i][j].data = malloc(sizeof(char)); // This line added.
strcpy(out[i][j].tag, "0");
out[i][j].vaild = 0;
strcpy(out[i][j].data, "0");
}
}
return out;
}

Change array size inside a struct

I'm trying to simulate a stack (pushing and poping values into the top of the stack) using structs and dynamic memory allocation in C and I have this struct:
...
#define max 5
typedef struct stack
{
int stk[max];
int top;
}STACK;
...
I successfully simulated the stack, but when it reaches its maximum size (stack is full) I want to change the value of max in order to keep adding (push) values to the top of the stack. In other words, i just want to reallocate the max value in the stk field of the struct, if that is possible.
Any suggestion is appreciated.
Using int stk[max]; is not dynamic memory allocation.
You need to have pointer int * stk; and initialize it with malloc. Then realloc when more memory is needed. And when stack is no longer needed, release it with free.
As #user694733 as pointed out you must use dynamic memory. An other example can be:
typedef struct stack
{
int top;
int max;
int stk[];
}STACK;
STACK *init_stack(int m){
STACK *st = (STACK *)malloc(sizeof(STACK)+m*sizeof(int));
st->top = 0;
st->max = m;
return st;
}
STACK *resize_stack(STACK *st, int m){
if (m<=st->max){
return st; /* Take sure do not kill old values */
}
STACK *st = (STACK *)realloc(sizeof(STACK)+m*sizeof(int));
st->max = m;
return st;
}
Now you can use that function in your program like:
void main(void){
STACK *st = init_stack(5);
.... do something bu you need more room....
st = resize_stack(st,100);
..... Now is small again .....
st = resize_stack(st,5);
}
Take care that every realloc call have a linear cost and so you cannot use it to add just a constant number of elements: better use a geometric expansion. Take a look to http://en.wikipedia.org/wiki/Dynamic_array as a start point for dynamic array.
Try it like this:
typedef struct stack
{
int *stk;
int top;
}
signed int array_resize(stack *s, size_t size)
{
if(!s) return -1;
s->stk = realloc(s->stk, size * sizeof(int));
return 0;
}
This reallocates the space for the array of integers. I don't know how else to make this work.

C Dynamically creating array of structs which include variable sized 2d array [duplicate]

I know how to create an array of structs but with a predefined size. However is there a way to create a dynamic array of structs such that the array could get bigger?
For example:
typedef struct
{
char *str;
} words;
main()
{
words x[100]; // I do not want to use this, I want to dynamic increase the size of the array as data comes in.
}
Is this possible?
I've researched this: words* array = (words*)malloc(sizeof(words) * 100);
I want to get rid of the 100 and store the data as it comes in. Thus if 76 fields of data comes in, I want to store 76 and not 100. I'm assuming that I don't know how much data is coming into my program. In the struct I defined above I could create the first "index" as:
words* array = (words*)malloc(sizeof(words));
However I want to dynamically add elements to the array after. I hope I described the problem area clearly enough. The major challenge is to dynamically add a second field, at least that is the challenge for the moment.
I've made a little progress however:
typedef struct {
char *str;
} words;
// Allocate first string.
words x = (words) malloc(sizeof(words));
x[0].str = "john";
// Allocate second string.
x=(words*) realloc(x, sizeof(words));
x[1].FirstName = "bob";
// printf second string.
printf("%s", x[1].str); --> This is working, it's printing out bob.
free(x); // Free up memory.
printf("%s", x[1].str); --> Not working since its still printing out BOB even though I freed up memory. What is wrong?
I did some error checking and this is what I found. If after I free up memory for x I add the following:
x=NULL;
then if I try to print x I get an error which is what I want. So is it that the free function is not working, at least on my compiler? I'm using DevC??
Thanks, I understand now due to:
FirstName is a pointer to an array of char which is not being allocated by the malloc, only the pointer is being allocated and after you call free, it doesn't erase the memory, it just marks it as available on the heap to be over written later. – MattSmith
Update
I'm trying to modularize and put the creation of my array of structs in a function but nothing seems to work. I'm trying something very simple and I don't know what else to do. It's along the same lines as before, just another function, loaddata that is loading the data and outside the method I need to do some printing. How can I make it work? My code is as follows:
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
typedef struct
{
char *str1;
char *str2;
} words;
void LoadData(words *, int *);
main()
{
words *x;
int num;
LoadData(&x, &num);
printf("%s %s", x[0].str1, x[0].str2);
printf("%s %s", x[1].str1, x[1].str2);
getch();
}//
void LoadData(words *x, int * num)
{
x = (words*) malloc(sizeof(words));
x[0].str1 = "johnnie\0";
x[0].str2 = "krapson\0";
x = (words*) realloc(x, sizeof(words)*2);
x[1].str1 = "bob\0";
x[1].str2 = "marley\0";
*num=*num+1;
}//
This simple test code is crashing and I have no idea why. Where is the bug?
You've tagged this as C++ as well as C.
If you're using C++ things are a lot easier. The standard template library has a template called vector which allows you to dynamically build up a list of objects.
#include <stdio.h>
#include <vector>
typedef std::vector<char*> words;
int main(int argc, char** argv) {
words myWords;
myWords.push_back("Hello");
myWords.push_back("World");
words::iterator iter;
for (iter = myWords.begin(); iter != myWords.end(); ++iter) {
printf("%s ", *iter);
}
return 0;
}
If you're using C things are a lot harder, yes malloc, realloc and free are the tools to help you. You might want to consider using a linked list data structure instead. These are generally easier to grow but don't facilitate random access as easily.
#include <stdio.h>
#include <stdlib.h>
typedef struct s_words {
char* str;
struct s_words* next;
} words;
words* create_words(char* word) {
words* newWords = malloc(sizeof(words));
if (NULL != newWords){
newWords->str = word;
newWords->next = NULL;
}
return newWords;
}
void delete_words(words* oldWords) {
if (NULL != oldWords->next) {
delete_words(oldWords->next);
}
free(oldWords);
}
words* add_word(words* wordList, char* word) {
words* newWords = create_words(word);
if (NULL != newWords) {
newWords->next = wordList;
}
return newWords;
}
int main(int argc, char** argv) {
words* myWords = create_words("Hello");
myWords = add_word(myWords, "World");
words* iter;
for (iter = myWords; NULL != iter; iter = iter->next) {
printf("%s ", iter->str);
}
delete_words(myWords);
return 0;
}
Yikes, sorry for the worlds longest answer. So WRT to the "don't want to use a linked list comment":
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char** words;
size_t nWords;
size_t size;
size_t block_size;
} word_list;
word_list* create_word_list(size_t block_size) {
word_list* pWordList = malloc(sizeof(word_list));
if (NULL != pWordList) {
pWordList->nWords = 0;
pWordList->size = block_size;
pWordList->block_size = block_size;
pWordList->words = malloc(sizeof(char*)*block_size);
if (NULL == pWordList->words) {
free(pWordList);
return NULL;
}
}
return pWordList;
}
void delete_word_list(word_list* pWordList) {
free(pWordList->words);
free(pWordList);
}
int add_word_to_word_list(word_list* pWordList, char* word) {
size_t nWords = pWordList->nWords;
if (nWords >= pWordList->size) {
size_t newSize = pWordList->size + pWordList->block_size;
void* newWords = realloc(pWordList->words, sizeof(char*)*newSize);
if (NULL == newWords) {
return 0;
} else {
pWordList->size = newSize;
pWordList->words = (char**)newWords;
}
}
pWordList->words[nWords] = word;
++pWordList->nWords;
return 1;
}
char** word_list_start(word_list* pWordList) {
return pWordList->words;
}
char** word_list_end(word_list* pWordList) {
return &pWordList->words[pWordList->nWords];
}
int main(int argc, char** argv) {
word_list* myWords = create_word_list(2);
add_word_to_word_list(myWords, "Hello");
add_word_to_word_list(myWords, "World");
add_word_to_word_list(myWords, "Goodbye");
char** iter;
for (iter = word_list_start(myWords); iter != word_list_end(myWords); ++iter) {
printf("%s ", *iter);
}
delete_word_list(myWords);
return 0;
}
If you want to dynamically allocate arrays, you can use malloc from stdlib.h.
If you want to allocate an array of 100 elements using your words struct, try the following:
words* array = (words*)malloc(sizeof(words) * 100);
The size of the memory that you want to allocate is passed into malloc and then it will return a pointer of type void (void*). In most cases you'll probably want to cast it to the pointer type you desire, which in this case is words*.
The sizeof keyword is used here to find out the size of the words struct, then that size is multiplied by the number of elements you want to allocate.
Once you are done, be sure to use free() to free up the heap memory you used in order to prevent memory leaks:
free(array);
If you want to change the size of the allocated array, you can try to use realloc as others have mentioned, but keep in mind that if you do many reallocs you may end up fragmenting the memory. If you want to dynamically resize the array in order to keep a low memory footprint for your program, it may be better to not do too many reallocs.
This looks like an academic exercise which unfortunately makes it harder since you can't use C++. Basically you have to manage some of the overhead for the allocation and keep track how much memory has been allocated if you need to resize it later. This is where the C++ standard library shines.
For your example, the following code allocates the memory and later resizes it:
// initial size
int count = 100;
words *testWords = (words*) malloc(count * sizeof(words));
// resize the array
count = 76;
testWords = (words*) realloc(testWords, count* sizeof(words));
Keep in mind, in your example you are just allocating a pointer to a char and you still need to allocate the string itself and more importantly to free it at the end. So this code allocates 100 pointers to char and then resizes it to 76, but does not allocate the strings themselves.
I have a suspicion that you actually want to allocate the number of characters in a string which is very similar to the above, but change word to char.
EDIT: Also keep in mind it makes a lot of sense to create functions to perform common tasks and enforce consistency so you don't copy code everywhere. For example, you might have a) allocate the struct, b) assign values to the struct, and c) free the struct. So you might have:
// Allocate a words struct
words* CreateWords(int size);
// Assign a value
void AssignWord(word* dest, char* str);
// Clear a words structs (and possibly internal storage)
void FreeWords(words* w);
EDIT: As far as resizing the structs, it is identical to resizing the char array. However the difference is if you make the struct array bigger, you should probably initialize the new array items to NULL. Likewise, if you make the struct array smaller, you need to cleanup before removing the items -- that is free items that have been allocated (and only the allocated items) before you resize the struct array. This is the primary reason I suggested creating helper functions to help manage this.
// Resize words (must know original and new size if shrinking
// if you need to free internal storage first)
void ResizeWords(words* w, size_t oldsize, size_t newsize);
In C++, use a vector. It's like an array but you can easily add and remove elements and it will take care of allocating and deallocating memory for you.
I know the title of the question says C, but you tagged your question with C and C++...
Another option for you is a linked list. You'll need to analyze how your program will use the data structure, if you don't need random access it could be faster than reallocating.
Your code in the last update should not compile, much less run. You're passing &x to LoadData. &x has the type of **words, but LoadData expects words* . Of course it crashes when you call realloc on a pointer that's pointing into stack.
The way to fix it is to change LoadData to accept words** . Thi sway, you can actually modify the pointer in main(). For example, realloc call would look like
*x = (words*) realloc(*x, sizeof(words)*2);
It's the same principlae as in "num" being int* rather than int.
Besides this, you need to really figure out how the strings in words ere stored. Assigning a const string to char * (as in str2 = "marley\0") is permitted, but it's rarely the right solution, even in C.
Another point: non need to have "marley\0" unless you really need two 0s at the end of string. Compiler adds 0 tho the end of every string literal.
For the test code: if you want to modify a pointer in a function, you should pass a "pointer to pointer" to the function. Corrected code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct
{
char *str1;
char *str2;
} words;
void LoadData(words**, int*);
main()
{
words **x;
int num;
LoadData(x, &num);
printf("%s %s\n", (*x[0]).str1, (*x[0]).str2);
printf("%s %s\n", (*x[1]).str1, (*x[1]).str2);
}
void LoadData(words **x, int *num)
{
*x = (words*) malloc(sizeof(words));
(*x[0]).str1 = "johnnie\0";
(*x[0]).str2 = "krapson\0";
*x = (words*) realloc(*x, sizeof(words) * 2);
(*x[1]).str1 = "bob\0";
(*x[1]).str2 = "marley\0";
*num = *num + 1;
}
Every coder need to simplify their code to make it easily understood....even for beginners.
So array of structures using dynamically is easy, if you understand the concepts.
// Dynamically sized array of structures
#include <stdio.h>
#include <stdlib.h>
struct book
{
char name[20];
int p;
}; //Declaring book structure
int main ()
{
int n, i;
struct book *b; // Initializing pointer to a structure
scanf ("%d\n", &n);
b = (struct book *) calloc (n, sizeof (struct book)); //Creating memory for array of structures dynamically
for (i = 0; i < n; i++)
{
scanf ("%s %d\n", (b + i)->name, &(b + i)->p); //Getting values for array of structures (no error check)
}
for (i = 0; i < n; i++)
{
printf ("%s %d\t", (b + i)->name, (b + i)->p); //Printing values in array of structures
}
scanf ("%d\n", &n); //Get array size to re-allocate
b = (struct book *) realloc (b, n * sizeof (struct book)); //change the size of an array using realloc function
printf ("\n");
for (i = 0; i < n; i++)
{
printf ("%s %d\t", (b + i)->name, (b + i)->p); //Printing values in array of structures
}
return 0;
}
If you want to grow the array dynamically, you should use malloc() to dynamically allocate some fixed amount of memory, and then use realloc() whenever you run out. A common technique is to use an exponential growth function such that you allocate some small fixed amount and then make the array grow by duplicating the allocated amount.
Some example code would be:
size = 64; i = 0;
x = malloc(sizeof(words)*size); /* enough space for 64 words */
while (read_words()) {
if (++i > size) {
size *= 2;
x = realloc(sizeof(words) * size);
}
}
/* done with x */
free(x);
Here is how I would do it in C++
size_t size = 500;
char* dynamicAllocatedString = new char[ size ];
Use same principal for any struct or c++ class.

Assigning a pointer in a struct to a variable

This program is supposed to create a dynamic memory vector. I'm pretty sure I'm using malloc correctly. My real problem is some syntax with pointers, particularly a pointer inside a struct.
I'm trying to access the address of an int pointer inside a struct so I can assign it to another pointer
My given struct is:
typedef struct{
int *items;
int capacity;
int size;
}VectorT;
and the function I'm trying to get to work is:
int getVector(VectorT *v, int index){
int *p;
p = v->items;//(2)
p -= v->size;
p += index;
return *p;
}
This is supposed to take the address of the items pointer subtract the number of items in the list and add the index of the desired item to the address of p. Then I return what is at the address of p.
I have a pretty strong feeling that line (2) is not the syntax I need.
Depending on what I've tried so far my program either crashes when getVector is called or it outputs (my best guess) some memory locations.
Here's the code that adds a vector:
void addVector(VectorT *v, int i){
if(v->size >= v->capacity){
//allocate twice as much as old vector and set old pointer to new address
v = (VectorT *) malloc(2 * v->capacity * sizeof(VectorT));
if(v == NULL){
fprintf(stderr, "Memory allocation failed!\n");//error catch
}
else{
v->capacity *= 2;//double the reported capacity variable
v->size++;//add one to the reported size variable
v->items =(int *) i;//add the item to the vector (A)<-----
}
}
else{
v->size++;//add one to the reported size variable
v->items =(int *) i;//add the item to the vector (B)<-----
}
}
I don't feel like my problem is in here, but if it is I have some suspicion at lines A & B...
Any insight would be much appreciated, Thanks!
Your dealing with pointers is wrong in at least these places:
The code with the comment "add the item to the vector" is very wrong: instead of adding an item, it overrides the pointer with an arbitrary int.
v->items =(int *) i;
should be
*(v->items) = i;
Your pointer arithmetic is incorrect: subtracting the size and adding an index will get you a pointer prior to the beginning of the allocated area, which is not correct.
You are assigning the results of malloc to a local variable v of type "pointer to vector". This assignment has no effect in the caller, because pointers are passed by value. If you wanted to re-assing the vector in the addVector, you should have taken VectorT **pv as the first parameter. This code fragment does not look right at all: it appears that you should be assigning v->items=malloc(2 * v->capacity * sizeof(int)) instead of v=malloc(...)
You do not free the old vector when you do a malloc, causing a memory leak.
You want the address of i, therefore:
v->items =&i;//add the item to the vector (A)<-----
Also, when calculating the size you'll want:
p -= (v->size*sizeof(int));
UPDATE:
You can also pass a pointer to i into getVector and just save that in v->items
int getVector(VectorT *v, int *index)
//...
v->items = i;
I see you're allocating memory for VectorT when you should be allocating memory for VectorT.items
void addVector(VectorT *v, int i){
if(v->size >= v->capacity){
//allocate twice as much as old vector and set old pointer to new address
v->items
int* tmp = malloc(2 * v->capacity * sizeof(int));
if(tmp == NULL){
fprintf(stderr, "Memory allocation failed!\n");//error catch
}
else{
int j;
for (j = 0; j < v->size; j++){
tmp[j] = v->items[j];
}
free(v->items);
v->items = tmp;
v->capacity *= 2;//double the reported capacity variable
v->items[v->size] = i;//add the item to the vector (A)<-----
v->size++;//add one to the reported size variable
}
}
else{
v->items[v->size] = i;//add the item to the vector (B)<-----
v->size++;//add one to the reported size variable
}
}
int getVector(VectorT *v, int index){
return v->items[index]
}

How to track malloc and free? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Simple C implementation to track memory malloc/free?
I need to know how much memory I have used till now in a C program and here is the pseudo code
#include <stdio.h>
int usedMemory =0;
void *MyMalloc(int size){
usedMemory = usedMemory +size ;
return malloc(size);
}
void MyFree(void *pointer){
/*****************what should i write here????*************/
}
int main(int argc, char *argv[])
{
char *temp1= (char *)MyMalloc(100);
char *temp2= (char *)MyMalloc(100);
/*......other operations.........*/
MyFree(temp1);
MyFree(temp2);
return 0;
}
Can anyone tell me what to write in the MyFree method(which decrements the amount of memory freed from usedMemory.
You could allocate few extra bytes more than asked, and store the size in the extra bytes, so that you could know the size later on, in MyFree function, with little calculation as:
unsigned long int usedMemory = 0;
void *MyMalloc(int size)
{
char *buffer = (char *) malloc(size + sizeof(int)); //allocate sizeof(int) extra bytes
if ( buffer == NULL)
return NULL; // no memory!
usedMemory += size ;
int *sizeBox = (int*)buffer;
*sizeBox = size; //store the size in first sizeof(int) bytes!
return buffer + sizeof(int); //return buffer after sizeof(int) bytes!
}
void MyFree(void *pointer)
{
if (pointer == NULL)
return; //no free
char *buffer = (char*)pointer - sizeof(int); //get the start of the buffer
int *sizeBox = (int*)buffer;
usedMemory -= *sizeBox;
free(buffer);
}
In C++, you could keep a global std::map<void*, std::size_t> around to track the size of each allocated block; your own allocator function would register the size when allocating, and the deallocation function would remove the entry. (Update: Or do as the linked question suggests and allocate a bit more memory and save the size there.)
The more fundamental problem is that this will probably only be of very limited use in a typical C++ program: Allocations there are done predominantly in two ways: 1) through explicit new expressions, which call ::operator new(), which in turn (usually) calls malloc(), and 2) through std::allocator<T>::allocate(), which on many platforms is implemented in terms of ::operator new().
The problem is that you don't have control over the specifics of your platform. You can replace the global operator-new to use your own MyMalloc(), but the default std::allocator might use malloc() directly and thus not be affected by that.
A cleaner approach for debugging purposes is to use an external tool like valgrind to track heap usage. For permanent internal use, tracking the allocation sizes is going to cause a significant performance hit, too.
You could allocate memory and store its size in the allocated block (error checking omitted for brevity):
unsigned int totalAlloc = 0;
void *MyAlloc(unsigned int size)
{
void *p;
totalAlloc += size;
p = malloc(size + sizeof(int));
*(int *) p = size;
return (void *)(((int *) p) + 1)
}
void MyFree(void *ptr)
{
ptr = (void *)(((int *) ptr) -1 );
totalAlloc -= * (int *) ptr;
free(ptr);
}
This code actually reserves more memory than requested in order to store the block's size in the (usually) first four bytes. This information can then be retrieved later on when you free the memory.
You need to manage a list of all malloc() you have done with pointer + size. Then you can search for the size in that list, and decrement it in free().
Check for example in that example how they are doing:
http://developers.sun.com/solaris/articles/lib_interposers_code.html#malloc_interposer.c
You might have other possibilities to track memory, like:
Valgrind with massif tool for tracking memory usage over time. You can even generate png output graphics
Interposed libraries. You can found some libraries that you can use by LD_PRELOAD=thelib.so ./yourprogram, and they will output some statistics like jemalloc
(A side note, please accept some answers to your question !)
you could try something like this... i'd strongly recommend to use this only for debugging purpose!
#define MAXMEMBLOCKS 10000
typedef struct {
int size;
void* ptr;
} memblock;
typedef struct {
int totalSize;
int current;
memblock memblocks[MAXMEMBLOCKS];
} currentMemory;
currentMemory mem;
void *MyMalloc(int size) {
if (mem.current < MAXMEMBLOCKS) {
mem.current += size;
mem.memblocks[mem.current].size = size;
mem.memblocks[mem.current].ptr = malloc(size);
return mem.memblocks[mem.current++].ptr;
} else {
// you needed more memblocks than estimated
return NULL;
}
};
int MyFree(void *pointer) {
int i;
for (i = 0; i < mem.current; i++) {
if (mem.memblocks[i].ptr == pointer) {
mem.totalSize -= mem.memblocks[i].size;
free(mem.memblocks[i].ptr);
mem.current--;
return 0;
}
}
// you tried to free a block wich hasn't been allocated through MyMalloc()
return -1;
}

Resources