pointer being freed was not allocated in C - c

Not sure what is wrong with the code below and why it is giving me the error "pointer being freed was not allocated". Using clang.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static char * messagePtr;
int main()
{
messagePtr = (char *)malloc(sizeof(char) * 800);
if(messagePtr == NULL) {
printf("Bad malloc error\n");
exit(1);
}
// //gameLoop();
char outputMessage[50] = "";
messagePtr = outputMessage;
free(messagePtr);
messagePtr = NULL;
return 0;
}

You assigned outputMessage, which is an array and is converted to a pointer to the first element of the array, to messagePtr, so messagePtr no longer points at what is allcated via malloc() or its family.
Passing what is not NULL and is not allocated via memory management functions such as malloc() invokes undefined behavior. (N1570 7.22.3.3 The free function)
Note that they say you shouldn't cast the result of malloc() in C.
Some of your options are:
1. Stop using malloc() for allocating buffer that will be thrown away.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static char * messagePtr;
int main()
{
// //gameLoop();
char outputMessage[50] = "";
messagePtr = outputMessage;
messagePtr = NULL;
return 0;
}
2. Free the buffer before throwing it away.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static char * messagePtr;
int main()
{
messagePtr = malloc(sizeof(char) * 800);
if(messagePtr == NULL) {
printf("Bad malloc error\n");
exit(1);
}
// //gameLoop();
free(messagePtr);
char outputMessage[50] = "";
messagePtr = outputMessage;
messagePtr = NULL;
return 0;
}
3. Use strcpy() to copy strings.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static char * messagePtr;
int main()
{
messagePtr = malloc(sizeof(char) * 800);
if(messagePtr == NULL) {
printf("Bad malloc error\n");
exit(1);
}
// //gameLoop();
char outputMessage[50] = "";
strcpy(messagePtr, outputMessage);
free(messagePtr);
messagePtr = NULL;
return 0;
}

The lines
char outputMessage[50] = "";
messagePtr = outputMessage;
create a char[50] and assign messagePtr the address of that array, thus removing the pointer to the malloced memory. The successive free call therefore tries to free messagePtr, not the memory allocated by malloc. Not only this, the mallocated memory will be lost since you have lost all reference (i.e., the pointer) to it.
I'm not entirely sure what you are trying to accomplish by messagePtr = outputMessage, so I can't really give you a hint on solving this - except to not reassign a pointer returned by malloc prior to freeing it.
Notes:
You do not need to cast void*, as returned by malloc, to other pointer types. There is an implicit conversion for that. Read why not to cast the return value of malloc.

messagePtr = (char *)malloc(sizeof(char) * 800);
makes messagePtr pointing to the location in Heap where malloc allocated 800 chars (e.g. 1005). This location has to be freed.
messagePtr = outputMessage;
makes messagePtr pointing to the location in Stack where 50 chars where automatically allocated (e.g. 505).
Automatic allocations can not be freed with free. They are deallocated automatically when the variable's scope ends.
Calling free on the automatically allocated memory is an error. free has to be called on location 1005 (according to the example).

Related

Realloc causing unreachable memory if pointer is not returned

I been trying to figure out why Valgrind reports unreachable memory and the buffer gets corrupted when i don't return the pointer (case 2) .
As i understand it i give read_input a pointer and it uses it. If realloc is caused i get a new pointer and replace the old one, so the pointer of input_buffer in main,and wherever there is that pointer it should have that new pointer, but it doesn't.
Is it maybe that i am passing literally the address ?
So the input_buffer in main has the old address as it was never changed? (My C is a bit rusty)
Is there a way to keep the input_buffer "updated" without returning the value like case 1 ? thus being able to write code like case 2 ?
(without having the buffer global/static)
#include "dev_utils.h"
#include "promt.h"
#include "sh_input.h"
int main(int argc, char *argv[]) {
// char *input_buff = (char *)malloc(CMD_BUFF * sizeof(char));
char *input_buff = (char *)malloc(1024 * sizeof(char));
if (!input_buff) {
fprintf(stderr, "Memory allocation failed at %s:%d! Exiting.\n",
"cs345sh.c", 8);
exit(1);
};
while (1) {
put_promt();
// 1. input_buff = read_input(input_buff);
// 2. read_input(input_buff);
parse_input(input_buff);
}
free(input_buff);
return 0;
}
#include "sh_input.h"
#include "dev_utils.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *read_input(char *input_buff) {
unsigned int input_buffer_size = CMD_BUFF;
unsigned int input_index = 0;
char input;
while(1) {
input = getchar();
if (input_index >= input_buffer_size) {
input_buffer_size += CMD_BUFF;
char *new_buff;
new_buff = realloc(input_buff, input_buffer_size);
if (!new_buff) {
fprintf(stdout, "Memory allocation failed at %s:%d! Exiting.\n",
"sh_input.c", 17);
exit(1);
};
input_buff = new_buff;
}
if (input == EOF || input == '\n') {
input_buff[input_index] = '\0';
return input_buff;
} else {
input_buff[input_index] = input;
}
++input_index;
}
// 1. return input_buff;
}
void parse_input(char *input) {
if (strcmp(input, "exit") == 0) {
free(input);
exit(EXIT_SUCCESS);
}
printf("%s\n", input);
}
Function arguments are passed by value in C. The input_buff parameter is a different object than the variable that you pass into the function when you call it (they have different memory addresses, even though the pointer value stored at these two addresses is initially the same). Thus, updating the parameter variable has no effect on the variable in the caller function.
So the caller function must take care of updating its own variable, which you can achieve by returning the new pointer, or as #UnholySheep has already pointed out in the comments to your question, you could instead pass a pointer to the variable to overwrite it from within the read_input function.

Segmentation fault when releasing a string in C

I have a "segmentation fault" error when I try to free the allocated memory of the string pointed from "new_job->jobs_adress" . I've allocated enough memory for my string (even if I allocate far beyond from what I need, I still have this problem), But there is still this error.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct job_t {
pid_t pid;
time_t creation_time;
bool stop;
bool foreground;
char * jobs_adress;
} Job;
int main() {
char * jobs_adress = "string";
/* creating an object of "Job" Type */
printf("another try");
Job * new_job = (Job*)malloc(sizeof(new_job));
if(!new_job) {
return;
}
/* allocating memory for a new string, and copies the old string
into the new string*/
int length2=strlen(jobs_adress);
char * str2 = malloc(length2+1);
strcpy(str2,jobs_adress);
new_job->jobs_adress=str2;
new_job->pid = 1;
new_job->creation_time = time(NULL);
new_job->stop=false;
new_job->foreground=true;
free(new_job->jobs_adress); // <=== the error is here
}
Job * new_job = (Job*)malloc(sizeof(new_job));
On this line, sizeof(new_job) is measuring the size of variable new_job.
new_job has type Pointer, and a pointer is (typically) 4 bytes.
So you allocate 4 bytes.
You intended to allocate enough space for a Job struct.
The line should've been:
Job * new_job = (Job*)malloc(sizeof(Job));

Change string with malloc in other function

how can I change string in other function when I am using malloc?
in main:
char *myString;
changeString(myString);
changeString(char *myString){
myString = malloc((size) * sizeof(char));
myString[1] = 'a';
}
Thank you
Parameters in C are passed by value. So to modify a variable within a function, you'll have to pass the pointer to it. For example, int * to int, and char ** to char *.
void changeString(char **myString){
// free(*myString); // add when myString is allocated using malloc()
*myString = malloc(2);
(*myString)[0] = 'a';
(*myString)[1] = '\0';
}
Allocate memory in main, then pass a pointer to start of allocated memory to the function.
Also pass a variable containing the size of the allocated memory to the function, so that you can ensure that the new text does not overflow the allocated memory.
The modified string is available from main.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void changeString(char *stringptr, int sz);
int main(void)
{
const int a_sz = 16;
/* allocate memory for string & test successful allocation*/
char *myString = malloc(a_sz);
if (myString == NULL) {
printf("Out of memory!\n");
return(1);
}
/* put some initial characters into String */
strcpy(myString, "Nonsense");
/* print the original */
printf("Old text: %s\n", myString);
/* call function that will change the string */
changeString(myString, a_sz);
/* print out the modified string */
printf("New text: %s\n", myString);
/* free the memory allocated */
free(myString);
}
void changeString(char *stringptr, int sz)
{
/* text to copy into array */
char *tocopy = "Sense";
/* only copy text if it fits in allocated memory
including one byte for a null terminator */
if (strlen(tocopy) + 1 <= sz) {
strcpy(stringptr, tocopy);
}
}

Mallocing char* with same length as another char* causes it become a copy?

I am currently trying to write a simple C program that creates a struct with a char* field and assigns it to have the same value as argv[1]. I then want to create another char* with the same length as argv[1], but for some reason the data inside already contains the same value as argv[1]. Here is my code so far:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
struct example{
char *str;
};
struct example* create(char *s){
struct example *p = (struct example*)malloc(sizeof(struct example));
char * copy = (char*)malloc(strlen(s));
strcpy(copy, s);
p->str = copy;
free(copy);
return p;
}
void new_char(struct example * t){
printf("original: %s\n", t->str);
char *w = (char *)malloc(strlen(t->str));
printf("why is this a copy? %s\n", w);
free(w);
}
void clean(struct example *t){
free(t);
}
int main(int argc, char **argv){
struct example * p = create(argv[1]);
new_char(p);
clean(p);
return 0;
}
Then when I compile and run this program using GCC 6.1, I get this out put
> gcc -Wall -g -o test test.c
> ./test "test value here"
> original: test value here
> why is this a copy? test value here
this code is wrong
struct example* create(char *s){
struct example *p = (struct example*)malloc(sizeof(struct example));
char * copy = (char*)malloc(strlen(s));
strcpy(copy, s);
p->str = copy;
free(copy);
return p;
}
first you need to allocate strlen + 1
Second you cannot free 'copy' here, p->str points at it, you now have a dangling pointer. To copy and malloc use strdup http://linux.die.net/man/3/strdup
struct example* create(char *s){
struct example *p = (struct example*)malloc(sizeof(struct example));
p->str = strdup(s);
return p;
}
The reason you got the same string is because you released your string back to the heap and then got it back again when you called malloc, this is purely luck, another time you might crash, get garbage,...
Look at this lines:
char * copy = (char*)malloc(strlen(s));
...
p->str = copy;
free(copy);
return p;
You alloc a block of memory, initialize it, store a pointer to it in your structure, and then free it! From that free() on, the p->str pointer points to freed memory, that is memory that must not be used.
What happens next? You do another:
char *w = (char *)malloc(strlen(t->str));
which, by chance, gets get memory just freed from the previous code, and since malloc() does not initialize the returned memory in any way, it happens to have the same string you just used.
What you see is actually garbage (uninitialized memory) that just happens to take the shape of a recent used text.
Summing up, your code has three problems:
You free the string you are returning in create()
You do not free the string in clean() before freeing the struct.
You try to print an uninitialized chunk of memory and wonder what the garbage means.
Hrre is the problem:
char * copy = (char*)malloc(strlen(s));
strcpy(copy, s);
p->str = copy;
free(copy);
You allocated a copy of original string and immediately free it.
char *w = (char *)malloc(strlen(t->str));
This line reuses previously freed memory and that's why you get the same content - the pointer is the same.
Note this happens in very simple scenarios and is specific to c library you use.
malloc doesn't initialize the memory it allocates. The second call to malloc happened to assign the same block of memory the first call to malloc has allocated (seeing as it had become unallocated when you called free). You cannot count on this.
Errors:
You need to allocate space for the NUL too. malloc(strlen(s)) should be malloc(strlen(s)+1).
You may not access unallocated memory, as you when you print t->str and when you try to find its length. You probably didn't mean to deallocate it. free(copy); should be moved to clean as free(t->str);.
Casting the value returned by malloc is necessary in C++, but is needless in C.
Tips:
strdup is a convenient shortcut for strlen+malloc+strcpy.
If you write
typedef struct { ... } example;
instead of
struct example { ... };
you can use example instead of struct example.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
typedef struct {
char *str;
} example;
example* create(char *s){
example *p = malloc(sizeof(example));
p->str = strdup(s);
return p;
}
void new_char(example * t){
printf("original: %s\n", t->str);
char *w = strdup(t->str);
printf("%s\n", w); // Prints uninitialized memory.
free(w);
}
void clean(example *t){
free(t->str);
free(t);
}
int main(int argc, char **argv){
example * p = create(argv[1]);
new_char(p);
clean(p);
return 0;
}

Why realloc doesn't work in this while loop?

I am anxious to know why realloc() doesn't work in my loop.I made a grep function which i tested on a large text file and suddenly the program crashed telling me "corruption of the heap" so I decided to break it up and try it on a smaller scale,but the problem persist.Can someone explain what is wrong?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void grep(const char *Pattern,FILE *file);
int main(void)
{
FILE *file;
if(fopen_s(&file,"file.txt","r"))
return 1;
grep("word",file);
fclose(file);
return 0;
}
void grep(const char *Pattern,FILE *file)
{
size_t size = 5*sizeof(char);
char *_Buf = (char*)malloc(size);
int n = 0, c;
while(c=getc(file))
{
_Buf[n++] = c;
if(c == '\n' || c == EOF)
{
_Buf[n] = '\0';
if(strstr(_Buf,Pattern))
printf("%s",_Buf);
if(c == EOF)
break;
n = 0;
}
if(n == size)
{
size += 5;
realloc(_Buf,size);
}
}
free(_Buf);
}
Calling realloc() on a pointer does not adjust the old pointer. It deallocates the old pointer and returns a new pointer containing the new allocation. You need to make use of the returned pointer afterwards.
From the C11 standard, chapter ยง7.22.3.5, The realloc function
void *realloc(void *ptr, size_t size);
The realloc function deallocates the old object pointed to by ptr and returns a
pointer to a new object that has the size specified by size. [...]
So, you need to collect the returned pointer, check against NULL and assign it back to the previous pointer, as you may.
That said, please see this discussion on why not to cast the return value of malloc() and family in C..
You are not assinging the returned pointer of realloc() to a variable/pointer:
realloc(_Buf,size);
Use:
char * _New_Buf = realloc(_Buf,size);
if(_New_Buf != NULL)
_Buf = _NewBuf;
else
; // add some error handling here
Otherwise, free() will also be free-ing the wrong memory pointed to by a possible invalid _Buf.

Resources