Realloc 2D and functions - c

I want to realloc a 2D matrix in a different function from main but unfortunately, I get an invalid pointer error. I have read other answers but I can't see where is my error. My code is:
void example(double* w, size_t s){
w=realloc(w,(s+1)*sizeof(double));
w[s]=3;
}
int main(int argc, char *argv[]){
double w[100][1];
int i;
for(i=0;i<100;i++){
example(w[i],sizeof(w[i])/sizeof(w[i][0])
}
free(w);
return 1;
}
so the first level of the array is always fixed but the second can change. What is wrong with this?
CORRECTION:
int main(int argc, char *argv[]){
double **w;
int i;
w=malloc(100*sizeof(double *));
for(i=0;i<100;i++){
w[i]=malloc(1*sizeof(double));
example(w[i],sizeof(w[i])/sizeof(w[i][0])
}
free(w);
return 1;
}

The w pointer is not dynamically allocated (it didn't come from realloc or malloc) so it is invalid to pass it as the argument to realloc. Also, you will need to pass the new pointer back to main if you want to free it in main.

You need to allocate memory before you can realloc or free memory. Also for every iteration you allocate memory you need to free it, you may free(w) but all it is doing is removing the memory reference to to w not actually freeing all the memory. For everything you malloc or realloc you need to go back through and free it so you don't have any memory leaks. You need would need a function like your example but to free all the memory instead of allocating it.
Just my thoughts

Related

How to free memory after returning the pointer

char* stringFunction(char *astrics){
char *string;
string = (char*)malloc(MAX);
string[0] = 0;
strcat(string,"Hello ");
strcat(string,astrics);
strcat(string,"\n");
return string;
//free(string);
}
int main(int argc, char* argv){
printf(stringFunction("Robert"));
printf(stringFunction("Robert Greene"));
return 0;
}
If no code is read after the return statement then how am I supposed to free the memory allocated for the pointer - string
When you return an allocated memory bloc, you tranfer ownership to the caller. That means that it is the responsability of the caller to later free the memory bloc when it has finished using it. Alternatively it could in turn transfer ownership to its own caller (and so on and so forth...)
Your program shouldn't free the memory until after it's finished using the memory. At the return statement, your program hasn't finished using that memory, because the main function still wants to print it! If you freed the memory inside stringFunction, then main would print freed memory.
Don't make the common mistake of thinking that you have to free pointers. You don't have to free pointers. You only have to free memory.
In this case main has to free the memory after it has finished using it and doesn't need it any more. This means we can't just write printf(stringFunction( since we need to put the pointer in a variable.
int main(int argc, char* argv){
char *mystring = stringFunction("Robert");
printf(mystring);
free(mystring);
mystring = stringFunction("Robert Greene");
printf(mystring);
free(mystring);
return 0;
}
Extra note: instead of printf(mystring); you should get into the habit of writing printf("%s", mystring);. Otherwise if you change "Robert Greene" to "Robert %s" your program will probably crash. But if you use printf("%s", mystring); it will just print "Hello Robert %s"

Is there a way to write a program which keeps using more and more memory? I want to write a simple C program for that

I used the following code but the VIRT column in top command shows constant memory allocated.
#include <stdio.h>
int main (int argc, char *argv[])
{
while(1)
{
int *pointer;
pointer = malloc(10 * sizeof(int));
*(pointer+3) = 99;
}
}
You need to Initialize the memory.
Use memset to initialize the memory:
memset(pointer, 0, the_size);
Also you could use calloc that not only allocates memory but also fills it with zeros for you:
pointer = calloc(10, sizeof(int));
about calloc:
The C library function void *calloc(size_t nitems, size_t size) allocates the requested memory and returns a pointer to it. The difference in malloc and calloc is that malloc does not set the memory to zero where as calloc sets allocated memory to zero.

difference between creating an array "normally" and with malloc

I was messing with C pointers to pointers in functions to learn. I created a string array, and wanted to change it in the function foo with a pointer to pointer. I then print it, just to see.
Problem is: if I create it "normally": char array[] = "yeah", the code doesn't work and I see a bunch of weird characters on the console. But, If I create it with a malloc, it works. I really want to understand the difference.
This works:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void foo(char **ptr);
int main(int argc, char *argv[]) {
char *array = malloc(sizeof("yeah")); //I need to malloc here, or it doesn't work. Why ?
strcpy(array, "yeah");
printf("array before : %s \n", array);
char *ptr = array;
char **pt = &ptr;
foo(&array);
printf("array after : %s \n", array);
free(array);
}
void foo(char **ptr) {
char *truc = malloc(sizeof(char) * 20); //I need to malloc here, else it doesn't work. Why ?
strcpy(truc, "then");
*ptr = truc;
}
but this doesn't, it prints nasty characters on the console:
void foo(char **ptr);
int main(int argc, char *argv[]) {
char array[] = "yeah"; //created "normally"
printf("array before : %s \n", array);
char *ptr = array;
char **pt = &ptr;
foo(&array);
printf("array after : %s \n", array);
free(array);
}
void foo(char **ptr) {
char truc = "then";
*ptr = truc;
}
What is the difference between:
char array[] = "yeah";
and
char *array = malloc(sizeof("yeah");
strcpy(array, "yeah");
The Array Way
First thing you should note: The code: char array[] = "yeah"; will work.
Note: if you do this, you do not call free(array) because it is not a pointer to dynamically-allocated memory, and does not need to be dynamically returned to the heap. It exists on the stack. Read on...
But the function foo() here is the problem. When foo() is called, the string truc (which also could be declared char truc[] = "then";) exists in a stack frame, which is a section of program memory, which only exists until foo() returns. If you change array to point to memory within that stack frame, what happens when that function returns? That stack frame becomes undefined, and you're left pointing at junk memory.
If you want to change the contents of the string in array, you could ensure the buffer is long enough, and foo() could strcpy(array, "then") into it. So, you're not changing the pointer itself, just the memory it points to. This isn't what I'd call good software design, but for the sake of an example, it would work for you. Like this:
void foo(char * ptr)
{
strcpy(ptr, "then");
}
So why doesn't it work without malloc() in main()?
When you don't malloc() in main(), array represents, as it suggests, an array. The identifier is not itself a pointer, it is an array; however, it decays to a pointer, or if you will, acts like one. That's why you could pass it off as one, if you wanted, like if you passed it to foo(). Now, if you reference the address of array, like &array, (char*)array, &array, &array[0] are all the same - pointers to the beginning of array. Your foo() is actually writing a memory address to the memory of array, in this case.
What does this do? Well, the technical answer is undefined behavior. But I would guess that it's writing a 32-bit integer (a memory address) to a chunk of memory that used to represent 4 8-bit characters in a string. So now you've corrupted exactly four characters. And, if foo() is using malloc() as you show, also introduced a memory leak.
The neat part of this is that your string is exactly four characters, so this shouldn't corrupt the null terminator '\0' at the end of the string. Let me guess, you see exactly four junk characters?

Function to free pointers not working

I'm learning C and trying to figure out an elegant way to free my pointers at the end of the execution.
After hours debugging and experimenting different things with the following code, I couldn't manage to figure out what I was doing wrong:
int ClosePointers(char *pointersToClose[], int arraySize) {
int index;
for(index = 0; index < arraySize; index++) {
char *pointer = pointersToClose[index];
free(pointer);
}
return (0);
}
int main(int argc, char *argv[]) {
char *pointersToClose[4];
char *pointer1;
char *pointer2;
char *pointer3;
char *pointer4;
pointersToClose[0] = pointer1;
pointersToClose[1] = pointer2;
pointersToClose[2] = pointer3;
pointersToClose[3] = pointer4;
pointer1 = malloc(10);
pointer2 = malloc(10);
pointer3 = malloc(10);
pointer4 = malloc(10);
/*some important code here using the pointers*/
ClosePointers(pointersToClose, 4);
return 0;
}
I'm getting the following error:
* glibc detected * /home/workspace/Debug/Test-POC: free(): invalid pointer: 0x00000038ce7b9850 ***
Could you help me out pointing what I'm doing wrong?
You're calling free on those pointers, but you never allocate any memory to them with malloc. In fact, the pointers you are trying to free are uninitialized, so they could contain anything.
When you set the values of pointersToClose, you're assigning the current value of pointer1, pointer2, etc., not whatever value they may contain when "some important code here using the pointers" runs.
Passing a pointer value to free that was not returned by malloc/realloc/calloc results in undefined behavior.
If you want to do this, try putting the address of each of the pointers in question in your array.
int ClosePointers(char **pointersToClose[], int arraySize) {
int index;
for(index = 0; index < arraySize; index++) {
char **pointer = pointersToClose[index];
free(*pointer);
}
return (0);
}
int main(int argc, char *argv[]) {
char **pointersToClose[4];
char *pointer1;
char *pointer2;
char *pointer3;
char *pointer4;
pointersToClose[0] = &pointer1;
pointersToClose[1] = &pointer2;
pointersToClose[2] = &pointer3;
pointersToClose[3] = &pointer4;
/*some important code here using the pointers*/
ClosePointers(pointersToClose, 4);
return 0;
}
Could you help me out pointing what I'm doing wrong?
You should use free() only on pointers that you allocated on the heap using the malloc() function.
What happens, is that within the heap (a reserved memory space), the length you gave as parameter to the malloc() function is allocated for your use, and it returns the address to the first word of that memory space so it can be assigned to a pointer.
When you use free(), it's deallocating that memory space so it can be reused.
Here, you create pointers variables that points to nothing (actually they point to a random value). So what's happening when you call free() on those variables is that you try to deallocate some random memory space that is not within the managed space, called the heap. As those addresses are unlikely to be allocated by malloc(), the free() function cannot know what to do with it, and therefore will return an error!
Read on about what are the stack and the heap to better understand what those are. Also, read the C programming language book by Kernighan and Ritchie where it's all well explained.
In your code. pointer1 is unitialized. It points to invalid memory. Passing that to free() invokes undefined behavior.
Quoting C11, chapter ยง7.22.3.3, (emphasis mine)
The free function causes the space pointed to by ptr to be deallocated, that is, made
available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if
the argument does not match a pointer earlier returned by a memory management
function, or if the space has been deallocated by a call to free or realloc, the
behavior is undefined.
You need to either
set that to NULL (null-pointer constant)
use malloc() or family to allocate free-able memory first.
That said, pointer2, pointer3 and pointer4 are undeclared in your code but probably that's a typo, so we can overlook it.
In order to free a pointer you must first have allocate memmory for it. You are going to free pointers that are never allocated. Try the following code to understnd what you did wrong
int AllocatePointers(char *pointersToClose[], int arraySize) {
int index;
for(index = 0; index < arraySize; index++) {
pointersToClose[index] = malloc(50*sizeof(char));
}
return (0);
}
int main(int argc, char *argv[]) {
char *pointersToClose[4];
char *pointer1;
char *pointer2;
char *pointer3;
char *pointer4;
pointersToClose[0] = pointer1;
pointersToClose[1] = pointer2;
pointersToClose[2] = pointer3;
pointersToClose[3] = pointer4;
AllocatePointers(pointersToClose, 4);
/*some important code here using the pointers*/
ClosePointers(pointersToClose, 4);
return 0;
}

how to free memory in C

I'm writing a C program but i'm getting some memory errors so i decided to make a small program to see when and how to deallocate memory.
My example :
int main() {
char *a=malloc(5);
a="mama";
char *b=malloc(strlen(a));
printf("%s\n",a);
strcpy(b,a);
free(a);
printf("%s\n",b);
return 0;
}
here i'm getting an error :
* Error in `./a': free(): invalid pointer: 0x0000000000400757 *
but when i change just one line :
int main() {
char *a=malloc(5);
strcpy(a,"mama");
char *b=malloc(strlen(a));
printf("%s\n",a);
strcpy(b,a);
free(a);
printf("%s\n",b);
return 0;
}
My second program is working well, so why i'm getting this error in the first?
i hope that you can explain me why.
In My Real program I'm doing like that :
char * getDate(){
char *date=malloc(5);
//some instructions here
return date;
}
int main() {
char *a=malloc(5);//im sure that a will not exceed 5 bytes
a=getDate();
return 0;
}
It's just a small example , and i don't know where to free memory .so how and where i can free memory , have I to free date or the char pointer?
Edited second Time:
void getDate(char *a){
//some instructions here
strcpy(a,"haha");
}
int main() {
char *a=malloc(5);
getDate(a);
int i= strlen(a);
printf("%s and the size is :%d\n",a,i);
free(a);
return 0;
}
what are the rules i have to follow to avoid memory errors.
many thanks.
In the line:
char *a=malloc(5);
You assign a with the address of a dynamically allocated memory block, but then in the line:
a="mama";
You reassign it with the address of the literal string constant "mama". Discarding the pointer to the dynamically allocated block so that when you call
free(a);
a is no longer a valid heap memory block, and cannot be deallocated.
Strings (and arrays in general) in C are not data first-class types and cannot be assigned. You should replace:
a="mama";
with
strcpy( a, "mama" ) ;
The assignment sets the pointer value - it does not copy "mama" to the memory points to by a. The strcpy() call on teh other hand copies the string to the dynamic memory block referenced by a.
In your second code fragment, you are "leaking" the memory allocated in main() since you have reassigned a without freeing the original block. Although in your example you have not free'd a, it remains freeable, because the allocation in GetDate() is dynamic. As a coding style, dynamically allocating memory in a function and returning its pointer is a bad idea since it makes it the responsibility of the caller to know that the memory was dynamically allocated and must be free'd, and it invites memory leaks.

Resources