I face annoying problem I do not quite understand ,
I have pointers of type int *
example code:
int* p_Memory_blocks;
int MemoryInit(int num_of_blocks, int block_size) {
int* head;
head = NULL;
for (int i = 0; i < num_of_blocks; i++) {
if ((head = malloc(block_size)) == NULL) {
printf("allocating memory failed");
for (int j = 0; j < i; j++) {
p_Memory_blocks = head;
head = *head;
free(p_Memory_blocks);
}
return 1;
}
head = &p_Memory_blocks;
p_Memory_blocks = head;
}
return 0;
}
int* MyMalloc() {
int* return_block = p_Memory_blocks;
p_Memory_blocks = *p_Memory_blocks;
return return_block;
}
void MyFree(int* block) {
*block = p_Memory_blocks;
p_Memory_blocks = block;
}
thats the code for initializing my pool for memory trying to connect the pointer to a linked pointer somehow
basically Im using pointers to build linked pointers
(my assignment is to build a fixed block memory pool allocator , I can only malloc the total amount of block_size * block_amount in bytes ,and I cannot use any more mallocs for any manager , the only thing I have is a global variable of type int * so i wanted to build a linked pointers and return the head to the user and then advance it to the next pointer)
in theory the p_Memory_blocks should advance to the last value because like linked list he is the head currently but the I get 'Unhandled exception thrown: read access violation.' and such
if fails after using twice
p_Memory_blocks = *p_Memory_blocks;
,so anyone got an explanation ? or a better way to implement it?
thank you very much !
Ive tried to malloc more memory , and variable types
A linked list node has two fields: next and value. You're not going to get far with just one field. Until you address this, you are doomed to fail.
Your immediate problem stems from this.
In your loop, n1 sometimes contains a pointer to the next node, and it sometimes contains a value, and you have no way to tell the two apart.
In technical terms, n1 will eventually hold 100, at which point *n1 results in undefined behaviour.
You need to address the issue that your structure does not contain enough information before you can proceed.
Related
I followed a quite straight forward pseudo code for implementing a linked list of a struct in c, here it is:
pseudo code for struct linked list
The problem i am facing is memory loss after adding the 4th node:
After the 4th addition, the 4th node points to the 3rd node, which points to a weird address.
prior to the 4th addition, the 3rd node pointed to the 2nd node - how did i lose the memory?
here's my code:
RailPart *headPart = NULL;
void createRailPart(char *partInfo, char *connectTypes){
char sPart[1];
char ePart[1];
char len[MAX_FIELD_SIZE];
char price[MAX_FIELD_SIZE];
char *noneDigit;
//allocate memory
RailPart *toPush = (RailPart*)malloc(sizeof(headPart));
if (toPush == NULL){
return;
}
//initialize data
sscanf(partInfo, "%[^,],%[^,],%[^,],%[^,]", sPart, ePart, len, price);
(*toPush).start = sPart[0];
(*toPush).end = ePart[0];
for (int i = 0; i < (int) strlen(connectTypes); i++){
if ((toPush)->end == connectTypes[i]){
(toPush)->ePartIdx = i;
}
if ((toPush)->start == connectTypes[i]){
(toPush)->sPartIdx = i;
}
}
(*toPush).len = (int) strtol(len, &noneDigit, BASE_10);
(*toPush).price = (int) strtol(price, &noneDigit, BASE_10);
//push the new node
toPush->nextPart = headPart;
headPart = toPush;
}
here's a documentation of the debugger, showing the memory loss i described
clear & informative debugger overview
Why am i losing this memory if i allocated it in the heap?
what should i do in order to handle the behavior?
Edit: issue fixed, but now i encounter a circle in my linked list - It seems that the computer doesn't remember it already allocated certain parts of the memory and it allocates it again. as you can see, at the 4th iteration, a not in use memory is being allocated, but after reading the sscanf line it changes it's address. how is this possible?
circle in linked list
so I have to write something like garbage collector for school project in C. I am stuck at problem with dynamic memory allocation. My function growActivePtrs() should enlarge global array of structs by one, but it does not seem to be working. I have read a ton on materials on dynamic allocation and tried many things, but I just cant find the mistake.
typedef struct activePtr
{
// pointer to actively used memory
void *memPointer;
// number of times this memory is referenced
int timesUsed;
} activePtr;
activePtr **activePointers;
size_t *ptrCount = 0;
bool growActivePtrs()
{
const size_t totalSize = *ptrCount + 1;
activePtr *temp = (activePtr *)realloc(*activePointers, (totalSize * sizeof(activePtr)));
if (temp == NULL) {
return false;
}
*activePointers = temp;
*ptrCount += 1;
activePointers[*ptrCount - 1]->timesUsed = 0;
activePointers[*ptrCount - 1]->memPointer = NULL;
return true;
}
Any help will be much appreciated. Thank you.
size_t *ptrCount = 0;
This defines ptrCount as a pointer to size_t, initialised to a null pointer. Unless you assign it the location of some actual size_t object (and it looks like you haven't), any attempt to access *ptrCount is doomed to fail.
There is no reason why this should be a pointer. You can just store a size_t directly.
As #user3121023 rightly points out in a comment, the same applies to your activePointers variable.
for learning purpose I'm implementing a stack with it's functions in c.
I added some small additional functionality to use malloc the first time and try to understand it properly.
I wrote a function which is initially creating my stack struct. The return value of the function is a new struct with an already allocate memory. What is the best way to handle a malloc exception in a function which return value should be a struct? Maybe should I design the function different? I'm aware that the printf is not doing it's job ;)
My Stack struct:
typedef struct Stack
{
int count;
int capacity;
int *data;
} Stack;
Creating a Stack instance:
Stack create_stack(int initialcapacity)
{
Stack new_stack;
new_stack.count = 0;
new_stack.capacity = initialcapacity;
if (!(new_stack.data = malloc(initialcapacity * sizeof(int))))
printf("not enough memory!");
return new_stack;
}
The function is called with the initial capacity of the stack:
Stack stack = create_stack(10);
A second question came up while I was writing a function to delete the Stack instance.
int delete_stack(Stack *stack)
{
stack->count = 0;
stack->capacity = 0;
free(stack->data);
stack->data = NULL;
return 0;
}
Am I able to remove also the struct instance itself? It feels not complete to just set the values back to 0 and direct int* to NULL.
Last but not least, I have a question to my push function. Also here I added some functionality which allows me to push something on the stack while it is already full:
void push(int value, Stack *stack)
{
if (stack->count == stack->capacity)
{
int *temp = malloc(stack->capacity * sizeof(int));
int i;
for (i = 0; i < stack->count; i++)
temp[i] = stack->data[i];
free(stack->data);
stack->data = NULL;
stack->data = malloc(stack->capacity * 2 * sizeof(int));
for (i; i > -1; i--)
stack->data[i] = temp[i];
free(temp);
temp = NULL;
stack->data[stack->count] = value;
stack->count++;
stack->capacity = stack->capacity * 2;
}
else
{
stack->data[stack->count] = value;
stack->count++;
}
}
Is it necessary to "free" the smaller array and put the pointer to NULL before I allocate a new array double the size?
If there is anything from my code which is unnecessary or not written properly, please let me know, I'm grateful for any hint which makes me better.
Cheeers,
me
I would do it with pointers. That is, your create_stack() would allocate a new Stack struct using malloc, then set the values to the struct and usee malloc again to allocate space for the Stack->data. Like this:
Stack* create_stack(int initialcapacity) {
Stack* new_stack = malloc(sizeof(Stack));
if (new_stack == NULL)
return NULL; // return null to tell the caller that we failed
new_stack->count = 0;
new_stack->capacity = initialcapacity;
new_stack->data = malloc(initialcapacity * sizeof(int))
if (new_stack->data == NULL)
{
free(new_stack);
return NULL;
}
return new_stack;
}
With this, we "handle" a malloc error by returning NULL, so the caller knows we failed.
Now that we have used malloc to allocate the Stack struct, you can (read: MUST) free the space taken by it using free(stack); in delete_stack().
In push(), the temporary array is not needed, that is, you could just right away allocate a bigger array, copy the contents to it from the original stack->data, free stack->data and set it to the newly malloc'd array:
int *temp = malloc(stack->capacity * 2 * sizeof(int));
// TODO: what if malloc fails?
int i;
for (i = 0; i < stack->count; i++)
temp[i] = stack->data[i];
free(stack->data);
stack->data = temp;
stack->data[stack->count] = value;
stack->count++;
stack->capacity = stack->capacity * 2;
Q. What is the best way to handle a malloc exception in a function which return value should be a struct?
There are at least three ways:
1) Instead of returning structure itself, return a pointer to it. This means two mallocs: one is for structure itself and another one is for data field. Returning NULL pointer means that something went wrong during construction.
struct Stack* create_stack(int initialcapacity) {
struct Stack* stack = malloc(sizeof(struct Stack));
...
return stack;
}
2) More flexible way is to pass pointer to already allocated structure. Flexibility comes from idea that calling code controls where to allocate structure: on stack or in dynamic memory. Return value of function may be used solely to notify calling code about errors:
bool create_stack(int initialcapacity, struct Stack* stack) {
...
}
// if calling code wants structure on stack (yeah, "stack" on stack)
struct Stack stack;
if (!create_stack(50, &stack)) {
die();
}
// if calling code wants it in dynamic memory
struct Stack* stack = malloc(sizeof(struct Stack));
if (!stack) {
die();
}
if (!create_stack(50, stack)) {
die();
}
3) If your program is not a 10,000+ LOC production code, easiest way may be to simply print error message and abort program immediately if allocation fails. Usually allocation errors are fatal: you can't recover in any meaningful way if there is not enough memory. You may even create a wrapper function over malloc to automatically catch such errors and exit:
void* my_malloc(size_t count) {
void* ptr = malloc(count);
if (ptr == NULL) {
fprintf(stderr, "Allocation failed");
exit(EXIT_FAILURE);
}
return ptr;
}
Q. Am I able to remove also the struct instance itself?
No, you can't. Because it is allocated on stack (the structure itself, not the data). If you want to delete structure itself, you need to use approach #1 from above.
And, by the way, there is no need to set zeroes and NULLs to fields. It doesn't delete anything. Such approach is used rarely and with only purpose to catch bugs (when calling code first deletes some structure and then tries to use it afterwards).
Q. Is it necessary to "free" the smaller array and put the pointer to NULL before I allocate a new array double the size?
Once again, you don't need to NULLify anything -- it doesn't delete anything. Instead of two mallocs and manual copying use realloc, which will do most of the work for you.
Generally, you should be able to declare a structure, then have an array of say 64 of them, with an integer to say which entry is on the top. Very simple, and no dynamic allocation. But 64 is pretty low, That's because stacks, recursion, and levels of nesting are intimately linked. Usually it should be possible to see that 64 is an insane level of nesting, and no legitimate input will ever even approach it. You then might need a guard to protect from malicious or corrupted input, but that just terminates the program or sub-routine.
If you can't establish a low sanity bound on a stack, it might that you still need one. Either it's a rare case where nesting goes very deep, or it's that you haven't approached the problem in the best way, but a sub-optimal program that still works is better than no program.
So you use the same structure, but the stack is set up with a call to
malloc() and, if it grows out of bounds, regrow with a call to realloc().
You might want to still sanity check it, but now sanity checks are
much higher, a million or so as opposed to 64. You also have to check that
realloc does not fail.
typedef struct
{
int x;
char astring[32];
} ENTRY;
static ENTRY *stack = 0;;
static int top = -1;
static int N = 0;
void push(const ENTRY *e)
{
/* grow logic like this */
ENTRY *temp = realloc(stack, newsize * sizeof(ENTRY));
if(temp)
stack = temp;
else
{
/* reallocation has failed but stack still valid */
free(stack);
N = 0;
top = -1;
/* for the sake of argument do this. We need temp to avoid
a memory leak */
fprintf(stderr, "out of memory\n");
}
/* push here, trivial */
}
int pop(ENTRY *e)
{
/* e is a non-const pointer. Fill and reset stack top */
}
You might want the stack global as in the example or you might want to
wrap it in a structure you pass about. Usually you'll want either pointers
or structures on the stack, but occasionally you might need a stack
of integers or floating point values.
There's no good way of handling memory allocation errors in C, especially
ones which can't happen (a computer with several GB of memory installed
is more likely to develop an electrical fault than to run out
of memory when asked for a couple of kilobytes). The usual rule is to
shunt up. But that makes the push call difficult, because every push
could potentially run the computer out of memory (but it can't really,
it's just your encapsulation allows the function to fail).
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
i have a linked list of srtings that i need to sort in alphabetical order
and i am tryping to copy the strings to an array and then sort and print them in alphabetical order
void DisplayAll(k *l,p *p)
{
int i,j;
p *temp;
temp = malloc(l->num*sizeof *temp);
for (i = 0; i < l->num; i++)
{
strcpy_s(temp[i].name, 20, p->name);
p = p->next;
i++;
}
for (i = 0; i < l->num - 1; i++){
for (j = i + 1; j< l->num; j++)
{
if (strcmp(temp[i].name, temp[j].name) > 0)
{
strcpy_s(temp->name,20, temp[i].name);
strcpy_s(temp->name[i],20, temp[j].name);
strcpy_s(temp->name[j],20, temp->name);
}
}
for (i = 0; i < l->num-1; i++){
printf("%s\n", temp[i].name);
}
}
this is the k struct and the p stuct
typedef struct p
{
char name[20];
struct p* next;
}p;
typedef struct k
{
int num;
p *head;
}k;
and i getting an Error evey time i run it
There's a couple of problems with your code:
First off: This doesn't look right at all:
strcpy_s(temp->name,20, temp[i].name);
strcpy_s(temp->name[i],20, temp[j].name);
strcpy_s(temp->name[j],20, temp->name);
according to the docs:
errno_t strcpy_s(
char *strDestination,
size_t numberOfElements,
const char *strSource
);
The first and last arguments are expected to be of the type char*. You've defined struct p .name as char[20], so temp->name[i] will be of type char.
I guess you're actually trying to do something like this:
//get struct p at offset i in temp, access member "name"
strcpy_s(temp[i].name, 20, temp[j].name);
Secondly: You're allocating memory for temp, but you fail to free it once you're done (ie when your function returns). You have, in other words, a memory leak. Sure, once your program exits, the memory is almost certainly going to be freed, but if you're writing programs that have to run for extended periods of time, and functions like this are getting called several times over, your memory consumption will gradually increase, and you don't want that to happen. In short, after your last loop (where you print everything out), add this:
free(temp);
Edit
You've added the free call now, and -correctly- wrap it in an if (temp). However: if malloc had returned a NULL pointer, don't you think you should've cought that at the beginning of the function?
temp = malloc(l->num * sizeof *temp);
if (!temp)
return;//or return int to indicate error or or exit EXIT_FAILURE; or something
There's no reason for you to reach the point where you free(temp) without having successfully allocated the memory.
Third: As #Bluepixy pointed out in his comment, there's a syntax error, too: the if (strcmp(temp[i].name, temp[j].name) > 0) branch is never closed properly: you're missing a closing bracket after the third strcpy_s call.
Lastly, you're allocating enough memory to accomodate l->num structs. You initialize them in such a way that every other struct will be assigned the name member of the next struct p in a list. You're not really making sure that p->next isn't a null pointer. This could cause problems (dereferencing a null pointer). So change the first loop into something like this:
int l_num = l->num;//you'll see why
for (i = 0; i < l_num; i+=2)//increment twice if you want/need to
{
strcpy_s(temp[i].name, 20, p->name);
p = p->next;
if (p == NULL)
{
l_num = i+1;//this is as far as we ought to go in the subsequent loops
break;//or handle error in some way
}
}
After this, replace all your ;i < l->num; conditions in your loops with i < l_num or j < l_num to avoid using uninitialized string values.
Just a final tip: If you're not working on anything too time critical, it might be useful to use calloc instead of malloc, especially when dealing with strings, or use memset(temp[i]->name, 0, 20); to ensure all char[] members are indeed empty strings.
If you find yourself using a lot of str* functions (strncat, strncpy and the like), even something as simple as temp[i]->name[0] = '\0'; can make life a lot easier.
How come the following code result in seg fault? Basically after I copy the head pointer to temp, the head pointer gone.
typedef struct address * paddress; // defines struct pointer
void addAddressToList(paddress head, int addr[])
{
if (head == NULL) {
//head->addrArray = addr; // if list is initially empty
} else {
paddress temp;
temp = head;
while (temp->right != NULL) {
temp = temp->right; // go to end of the list
}
paddress newAddress = (paddress)malloc(sizeof(paddress*));
newAddress->intAddr = addr;
newAddress->right = NULL;
newAddress->left = temp; // connect the new address
temp->right = newAddress;
}
}
main() {
paddress addressListHead;
addressListHead = (paddress)malloc(sizeof(paddress*));
int intAddr1[] = {1,2,3,4,5,6,7};
char hexAddr1[] = "123456";
int intAddr2[] = {16,14,13,12,11};
char hexAddr2[] = "fedcb";
addressListHead->intAddr = intAddr1;
addressListHead->hexAddr = hexAddr1;
addAddressToList(addressListHead, intAddr2);
}
paddress addressListHead;
addressListHead = (paddress)malloc(sizeof(paddress*));
It seems to get rid of the compilation error, you have type casted what malloc is returning to paddress. addressListHead is a pointer, which means it can hold the address of an object but not the address of a pointer. The malloc here statement doesn't create an object. You need to change this -
addressListHead = (paddress)malloc(sizeof(paddress*));
to
addressListHead = (paddress)malloc(sizeof(struct address));
in main and addAddressToList functions.
Segmentation fault :
else {
paddress temp;
temp = head;
while (temp->right != NULL) {
temp = temp->right; // go to end of the list
}
I understand paddress::right is a pointer with the fact you are comparing it to NULL. But what is temp::right is initialized to. It is pointing to some garbage address and so you cannot ask for it to compare with NULL. Make it point to a valid memory location.
There is more than one problem in your code.
Firstly, the usual advice: stop using sizeof with type names (as much as possible). Use sizeof with expressions, not types. Type names belong in declarations and nowhere else.
Your problem with memory allocation could have been prevented if you used this malloc idiom
T *p = malloc(n * sizeof *p);
i.e. sizeof should be applied to *p, where p is the pointer to the array you are allocating and n is the total number of elements in that array. That way you never have to guess what type name you should specify under sizeof (an that way your code becomes type-independent).
In your case you are allocating just one object, so the code should look as
paddress newAddress = malloc(sizeof *newAddress);
(And don't cast the result of malloc - there's absolutely no point in doing that).
Secondly, when you the head element of the list, you need to initialize all the fields. Yet you never initialize right (or left) in the head element. Hence the crash even when the correct amount of memory is allocated.
In main(), you want
addressListHead = (paddress)malloc(sizeof(address));
That makes sure you get enough bytes to hold an address.
First error:
addressListHead = (paddress)malloc(sizeof(paddress*));
paddress* means a pointer to paddress which itself is a pointer to struct address. Hence paddress* is a pointer to a pointer to struct address. You would want to do:
addressListHead = (paddress)malloc(sizeof(struct address));
Also, I see that you made a similar mistake yesterday. Why do I get a seg fault? I want to put a char array pointer inside a struct
It's important to understand the concept of pointers properly. I would definitely recommend you to go through some tutorials on pointers. If you need help with that, let me know.