My goal is to append a List to the end of an array. When i try to execute it give me segmentation fault.
I tried to make a little debug and the istruction that give me prolem is in the for cicle:
array[i] = tmp[i];
This is my code:
int i;
List *tmp = array;
array = (List *)malloc((dim+1) * sizeof(List));
for (i = 0; i < dim; i++) {
array[i] = tmp[i];
}
dim++;
array[dim-1] = (List)malloc(sizeof(struct TList));
memcpy(array[dim-1], set, sizeof(struct TList));
return array;
Where "dim" it's a global variable that i use to track the dimension of the array
I know that probably it's simple to do, but i really don't know how to solve this problem.
Thanks for help
First remark :
int i;
List *tmp = array;
array = (List*)malloc((dim+1) * sizeof(List));
for (i = 0;i < dim;i++){
array[i] = tmp[i];
}
Can be just that :
array = realloc(array, (dim+1) * sizeof(List));
in array[dim-1] = (List)malloc(sizeof(struct TList)); why the type in the cast is not also the type in the sizeof ?
But the true question is what do you expect doing that assignment except to loose memory through a memory leak ?
That line must be removed.
What are the definition of TList and list and the type of set ?
The line
memcpy(array[dim-1], set, sizeof(struct TList));
is wrong and must be (set must be a List)
array[dim-1] = set;
because array is vector of List, not a vector of List *
Related
If I have a variable called Tree * myTree, how could could I put this variable into an array of Tree*?
For example, I want to do something like:
Tree *allTrees[10];
allTrees = malloc(sizeof(Tree) * 10;
for (int i = 0; i < 10;i++)
{
allTrees[i] = malloc(sizeof(Tree));
}
allTrees[0] = myTree;
What am I doing wrong here?
You don't need to do
allTrees = malloc(sizeof(Tree) * 10);
because you are already allocating the array on the stack:
Tree *allTrees[10];
The rest should be fine.
I've run into a problem with structs which I believe is caused by incorrect mallocs, or possibly rather my reallocs. I've cut down the code as much as possible to only show what I believe could be relevant, so nearly all the actual operations are omitted.
The struct I have looks as follows:
struct poly_t {
int nvars, *factor, *exp;
};
The value that's acting weird is nvars, which to me would signify that I'm somehow not reserving memory properly. What I do is that I first have a function that creates and fills the struct, then I have another function where I send two of these structs in and create a third identical struct. When editing the value of nvars in this third struct, it very rarely also edits the value of nvars in the first struct. When running gdb, it shows the exact row it happens on is when I do thirdp->nvars++; in my mul function.
So with this function I create my first and second structs (a and b).
poly_t* new_poly_from_string(const char* a){
struct poly_t* p = malloc(sizeof(struct poly_t));
p->nvars = 0;
p->factor = malloc(strlen(a) * sizeof(int));
p->exp = malloc(strlen(a) * sizeof(int));
for (int i = 0; i < strlen(a); i++){
//do stuff to put a into p, using at most p->factor[p->nvars] and the same for p->exp
p->factor = realloc(p->factor, p->nvars*sizeof(int));
p->exp = realloc(p->exp, p->nvars*sizeof(int));
printf("%d", p->nvars); //At this point, nvars is the correct value
return p;
}
And below is the function that works in 9/10 cases but in some rare cases it doesn't. I've marked the exact row that changes a->nvars with an arrow -->.
poly_t* mul(poly_t* a, poly_t* b){
struct poly_t* thirdp = malloc(sizeof(struct poly_t));
thirdp->nvars = 0;
thirdp->factor = malloc((a->nvars + b->nvars) * sizeof(int));
thirdp->exp = malloc((a->nvars + b->nvars) * sizeof(int));
for (int i = 0; i < a->nvars; i++){
for (int j = 0; j < b->nvars; j++){
for (int k = 0; k < p->nvars; k++){
if (p->exp[k] == a->exp[i] + b->exp[j]){
p->factor[k] += a->factor[i]*b->factor[j];
found = 1;
break;
}
}
if (!found){
p->factor[p->nvars] = a->factor[i]*b->factor[j];
p->exp[p->nvars] = a->exp[i] + b->exp[j];
--> p->nvars++; //This is the row that changes a->nvars according to gdb
}
}
}
return thirdp;
}
Here's what I got when running gdb while trying to figure out what was changing a->nvars. Note that p is the same as thirdp above, I just renamed it here for clarity.
edit: Readded the actual code in the mul function
You are allocating space for the sum of the number of integers
a->nvars + b->nvars
I wonder what you do in
//fill thirdp->factor and thirdp->exp
As you have nested for loops I suspect you may be generating
a->nvars * b->nvars //multiply
items and hence running off the end of allocated space. You now show us the code and we see
if (!found){
// --- here ----
p->factor[p->nvars] = a->factor[i]*b->factor[j];
p->exp[p->nvars] = a->exp[i] + b->exp[j];
p->nvars++;
}
At the point I mark here you should check the value of p->nvars, I think it has the possibility to reach a value greater than (a->nvars + b->nvars).
I think to be safe allocate the space for (a->nvars * b->nvars) ints.
The problem was as I believed in the mallocs. Specifically the following two rows:
thirdp->factor = malloc((a->nvars + b->nvars) * sizeof(int));
thirdp->exp = malloc((a->nvars + b->nvars) * sizeof(int));
I simply wasn't allocating enough memory which caused the weird behaviour. What I wanted was:
thirdp->factor = malloc((a->exp[0] + b->exp[0]) * sizeof(int));
thirdp->exp = malloc((a->exp[0] + b->exp[0]) * sizeof(int));
Unfortunately since I didn't give any of the indata, or really much context, you guys probably couldn't have figured that out <.< Sorry!
I've just re-start learning C, but i'm really confused with some memory management details.
I'm getting
pointer being freed was not allocated ... Abort trap
for the code below. Do i really need 1 free per malloc? Why my code is wrong?
Thanks!
#define N 9
typedef struct
{
int MAX_LIST_SIZE;
int length;
int *ini;
}List;
/* allocates new List and its data */
List *newList(int size)
{
List *list = malloc(sizeof(List));
list->MAX_LIST_SIZE = size;
list->length = 0;
list->ini = malloc(sizeof(int) * size);
return list;
}
/* add some value to the list */
void addList(List *list, int val)
{
if (list->length < list->MAX_LIST_SIZE)
list->ini[list->length++] = val;
else
fprintf(stderr, "Error: add(): List is full.\n");
}
/* get an array of N*N lists malloc-ed Lists */
List *gridList()
{
int i, j;
List *cells = malloc(sizeof(List) * N * N);
for (i = 0; i < N * N; i++)
{
/* malloc is called inside NewList()*/
cells[i] = *newList(N);
for (j = 0; j < N; j++)
addList(&cells[i], j + 1);
}
return cells;
}
/* inside main */
List *cells = gridList();
/* use cells ... */
/* free */
for (i = 0; i < N * N; i++)
{
free(cells[i].ini);
/* line below causes CRASH */
free(&cells[i]);
}
You do :
cells[i] = *newList(N);
which sets each element in cells to a copy of the list dynamically allocated by newList. So newList dynamically allocates a list, then you take the pointer to that dynamically allocated List, dereference it, and copy it into cells[i]. So then later on when you go to free() each element:
free(&cells[i]);
It doesn't work because each element in cells[i] is a List, not a List * (list pointer) allocated by malloc().
So you have two options. One (bad one) is to just remove that last free() line since there's nothing to free. However, this just covers up a larger problem which is that you now have memory leaks because you can't go back and free the dynamically allocated Lists created with newList().
Instead it's likely you want to have an array of pointers to the lists, which you can do by changing it to:
List **cells = malloc(sizeof(List*) * N * N);
so that cells[i] refers to a List *. newList() returns such a pointer, so you would change that line to:
cells[i] = newList(N);
similarly, addList() takes such a pointer, so you'd simply change that line to:
addList(cells[i], j + 1);
since &cells[i] would pass it the address of the pointer, which is not what you want.
Finally, change the free statements to:
free(cells[i]->ini); // ->init because cells[i] is now a pointer to a List, List *
free(cells[i]);
The problem is you are allocating an array of lists, copying the full contents of your lists into the array elements, and then trying to free them. The original allocated List records are a memory leak, and the free calls are indeed trying to free memory that was not malloc'ed (or more exactly were malloc'ed in a single big block).
You want an array of pointers to pointers to hold your lists:
/* get an array of N*N lists malloc-ed Lists */
List **gridList()
{
int i, j;
// VV note change here
List **cells = malloc(sizeof(List*) * N * N);
for (i = 0; i < N * N; i++)
{
/* malloc is called inside NewList()*/
cells[i] = newList(N); // << Note change here.
for (j = 0; j < N; j++)
addList(cells[i], j + 1);
}
return cells;
}
/* free */
for (i = 0; i < N * N; i++)
{
free(cells[i]->ini); // << and here
/* line below causes CRASH */
free(cells[i]); // << and here
}
free(cells);
I have:
uint64_t *list;
if((list = malloc(10 * sizeof(uint64_t))) == NULL){
errx(1, "malloc");
}
I need to populate this array, increment the address of it.
I mean:
(*list)++;
list = 1;
(*list)++;
list = 2;
(*list)++;
list = 3;
(*list)++;
list = 4;
How do I do that?
You can use the allocated memory like a normal array:
list[0] = 1;
list[1] = 2;
/* etc. */
Edit:
What you are doing is increase the first entry in the "array" which probably contains a value you don't expect, then you reassign the pointer so it no longer points to your allocated memory, and so on. Also, if you really want to "increment the address" of the allocated memory, it's just simple as list++, however this is also changing the pointer so you loose the original allocated address and can not free it later (unless you save it.)
you can use a loop
for(int i = 0; i < 10; i++) {
list[i] = i+1;
}
I have a pointer to a struct list* ptr
The struct contains a char and a pointer to the next struct and these are used for an array of structures like so:
list array[setSize]; //setSize is defined as 20
Without using malloc, I need to initialize list* ptr so that it has all the elements of the array.
I have tried the following and I get a segmentation fault. I believe I am utterly misunderstanding how pointers work. (I haven't touched C in a long while)
int j = 0;
ptr = sizeof(array[j]); //i was thinking this would allocate space
for(j; j < setSize; j++)
array[j].next = array[j+1].next;
ptr = array; //i thought this would point to the beginning of the array
I have looked at a lot of sites about C and linked list. I had books but they don't give enough detail about this particular use of pointers or structures. I have been trying this for a while but I am sure I am missing something.
I just need to understand where I am going wrong and what direction to head towards.
Thanks for any and all help.
Below is a Re-post with more code:
//this should initialize array so that ptr contains all array elements
void initialize ( list array[] ) {
int j;
for(j = 0; j < setSize - 1; j++){
array[j].next = array[j+1].next; //using the & does not seem to work, so I don't use it
array[j].next = NULL;
}
ptr = &(array[0]);
}
Later on I am using this in my own malloc function (which is where the seg fault happens)
//this should allocate a new list cell in array
list* my_malloc () {
list* temp;
temp = ptr;
if(ptr = 0) {printf("Empty!\n"); return;}
else{ //the next line creates the seg fault
ptr = (*ptr).next;
}
return temp;
}
list* cell ( char n, list* next ) {
list* x = my_malloc();
x->value = n;
return x;
x->next = next;
return x;
}
main ( void* argv, int argc ) {
initialize(array);
list* x = nil;
char ch = a;
int i;
for ( i = 0; i < setSize; i++ )
x = cell(ch,x);
for ( i = 0; i < 10; i++ ) {
list* y = x->next;
my_free(x); //this is my own free function
x = y;
};
for ( i = 0; i < 10; i++ )
x = cell(ch,x);
}
Everything you have there is pretty close to making sense except for this line:
ptr = sizeOf(buffer[j]);
I presume you mean sizeof there? At any rate, that operation is meaningless (and illegal, since you're trying to assign an integer to a variable of pointer type). You don't need to allocate any memory, your definition of array already does that.
You do have a problem with your for loop - you're going go one past the end of the array, which might be what's causing your segmentation fault. It's either that or the fact that you didn't initialize j, so it could be accessing some memory it shouldn't. I think you probably want something like:
for (j = 0; j < setSize - 1; j++)
{
array[j].next = &array[j+1];
}
Edit: The reason for your segfault is that this line:
if(ptr = 0) {printf("Empty!\n"); return;}
Sets ptr to 0. I think you want a == there. Another point - you say "using the & does not seem to work, so I don't use it". That probably means your list structure is declared incorrectly, or at least in a pretty nonstandard way. You should probably show more of your program - it seems like you have some pretty fundamental misunderstandings of how pointers work.
I think this is what you want:
#define ARRAY_LENGTH (20)
struct list
{
char ch;
struct list* next;
};
struct list array[ARRAY_LENGTH]; // array's memory is allocated with this, no need to use malloc
struct list* ptr = &(array[0]); // ptr now points to the 1st item in the array
int j; // I'm declaring 'j' outside of the for loop just in case you are using c and not c++
for(j=0 ; j < ARRAY_LENGTH-1 ; j++)
array[j].next = &(array[j+1]); // .next of jth item in array now points to the following item
array[j].next = NULL; // assign .next of last item to NULL, so you know when you have reached the end of the array when traversing it.
Note that the for-loop is executed for (ARRAY_LENGTH - 1) items, not ARRAY_LENGTH items, since array[j+1] would be out of bounds in the last iteration.
Now that you have ptr pointing to the 1st item in the array, you can traverse through it with something like:
struct list* curItem; // this will be your iterator to traverse the array
curItem = ptr; // initialize your iterator to point to the 1st item
while(curItem != NULL) // note that with this, you don't need to know the length of the array
{
printf("Current item's .ch is %c\r\n", curItem->ch); // don't forget to include the header for printf
curItem = curItem->next;
}
array[j].next = array[j+1].next;
That won't work since array[j+1].next isn't defined. Depending on how buffer[i].next is defined, you should be able to do this:
array[j].next = &array[j+1];
sizeof doesn't allocate space. If you don't want to use malloc, you have to allocate your space either on the stack or wherever globals are stored (probably bss). Since you presumably do that with your array definition, ptr = &buffer[j] will get you a pointer to the jth element of the buffer. I think you meant "addressof" instead of "sizeof", which is spelled & in C. Of course, buffer isn't array. That's either a typo or something very wrong.
Anyway, your code is a bit misordered. What you probably wanted to do was initialize your pointer to array, then iterate through the elements, setting next:
ptr = array;
for (j = 0; j < setSize; j++)
array[j].next = &array[j+1];
array[setSize - 1] = NULL; // The last element was set to a lie.