Find the mistakes in the following codes - c

I need to find the mistakes in the following code and I'm not sure I found all of them.
1)
char *str;
str=(int*)malloc(10);
I'm not sure if its allowed to allocate Integer and convert it to char but the first mistake I see is that the memory was not freed.
same with :
2)
char *str;
str=(char*)malloc(10);
free();
The memory was not freed right - should be ( free(str);).
and if it's in the same code with the previous one then we allocated another memory and didn't free the previous one.
Am I right ? I'm not sure if you can allocate integer and convert to char tho.
Thank you in advance.

First of all, you don't type-cast the result of malloc at all.
Second, type-casting a char pointer to int pointer is just plain undefined behavior in C. You have a char sized region of memory from which you will be reading an int; the result is plain undefined.
Lastly, you need to pass your pointer inside free as argument to release the allocated memory associated with it. See free's reference. free is not a keyword in C and needs to be imported from stdlib.h. free is not intelligent enough like a garbage collector (you can't just call it without an argument and have all un-used resources freed, which the syntax won't allow anyway) which will automatically find weak references (like in Java) and garbage collect it. There is no automatic garbage collection in C.

I can find five potential problems with the code in your first example:
The functions malloc (and free) are declared in stdlib.h so you need to #include <stdlib.h>.
To keep track of the length of an allocated buffer it's a good idea to introduce a length variable together with the character pointer str. I always use the suffix Len, so then the name is strLen.
Casting the result of malloc is not needed or recommended in C.
The result of malloc can be NULL so we need to check if that's the case. A good approach is to use a memory allocation macro so we can do the check in one place.
When we are done with str we need to free it with free(str);
Here is the code with all suggested changes:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NEW_ARRAY(pointer, length) \
(pointer) = malloc((length) * sizeof (pointer)[0]); \
if ((pointer) == NULL) { \
fprintf(stderr, "Memory allocation failed: %s\n", strerror(errno)); \
exit(EXIT_FAILURE); \
}
int main(void)
{
const char strLen = 10;
char *str;
NEW_ARRAY(str, strLen);
/*...*/
free(str);
return 0;
}

Related

why couldn't use a pointer in gets in C? such as char *str replace char str[40] in gets(str)

#include <stdio.h>
int main ()
{
char str[40];
printf("Enter a string : \n");
gets(str);
printf("You entered: %s\n", str);
return 0;
};
in above code, if replace str to a pointer, char *str. Then NULL is out. Suppose gets defined by char *gets(char *str), it should use a pointer instead of array. All examples I saw are array not pointers. Thanks.
function gets() is depracted your libc/compiler might ignore it. try use fgets() instead.
#include <stdio.h>
int main ()
{
char str[40];
printf("Enter a string : \n");
if (fgets(str, sizeof(str), stdin) != NULL)
{
printf("You entered: %s\n", str);
}
return 0;
};
also if you want to don't use stack you need to give pointer that points allocated space. in code str also can be char *str = malloc(40); then change sizeof(str) to 40 since str is no longer stack.
Really interesting question, I have been asked this question a lot!
you should have a bit background of pointers and memory to understand what is happening.
first let's have a brief review about pointers and memory:
our computer have some memory and we can use it in programming, anything that we store (in runtime) for example an int, array of doubles, some complex struct and strings(that they are array of characters) should be somewhere in memory.
pointers contain address of somewhere in memory, some of them know about that memory (how to read/write value) some of them don't.
there is a special value for pointers (NULL) that means nowhere, if pointer is pointing to NULL, that pointer is pointing not nowhere (obviously nowhere is not a valid address in memory)
array is specific type of pointer, a const pointer that is pointing to already allocated memory in stack.
and about gets function: let's think we want to re-implement such function (namely my_gets) , how we suppose to do that? how to return a string (array of characters)?
these are options (as far as i know):
creating a local array in our function and fill it. then we should return it? no we cant! because that array is in stack of our function and after ending the function, our function data including this array will be popped automatically (handled by compiler).
although nobody forbid us from returning that array, but that would cause dangling pointer problem.
allocating some space rather than stack (heap) and fill that. this is perfectly fine and there is methods and do this! for example readline (not in ansi c, you can find it here) will do this. the drawback of this method is that you should take care of that memory and free it later, it also may be not to optimum way and you may should copy that string to your already allocated memory
the last way (and way that gets use) is getting a pointer that is already pointing to a valid memory and fill that memory. you already know that gets want a pointer as input, I add that, that pointer should point to a valid and accessible memory that gets can fill it. if pointer is pointing to NULL (or maybe uninitialized and pointing to some where random) gets will fail writing and cause undefined behavior (segmentation fault for example)
some final points:
array solution work because array name is pointer that pointing to valid memory (array in stack) so it's OK and easy to understand.
If we don't want to use array, we can point our pointer to a valid memory, we need to use malloc/calloc to allocate a block of memory. see this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int size = 40 * sizeof(char);
char* p = malloc(size);
printf("Enter a string : \n");
if (fgets(p, size, stdin) != NULL) {
printf("You entered: %s\n", p);
}
free(p);
return 0;
}
gets is not secure because it doesn't care how much memory we have, it writes until and string ends and it may cause buffer overflow, better option (as people said) is fgets because it care memory size and will not exceed that. but my answer doesn't care it's fgets or gets.

Typedef char pointer allocation of string

I am trying to understand a code that has the typedef char * I am supposed to allocate memory enough for the string "Pointer of" and "Redundancy".
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
typedef char* DString;
DString dstring_initialize(const char* str);
int main(void)
{
DString str1, str2;
str1 = dstring_initialize("Pointer of ");
str2 = dstring_initialize("Redundancy ");
return 0;
}
DString dstring_initialize(const char* str)
{
str = malloc((strlen(str)+1)*sizeof(DString));//mycode
return str;//mycode
}
I am 100% sure that I am doing it completely wrong. The only thing I am supposed to do is change the part where it says mycode. It was sent to me like that, but as I said before, I don't know how it works, and if someone could explain it to me in detail, I would appreciate it
In the code below you allocate too much memory:
str = malloc((strlen(str)+1)*sizeof(DString));//mycode
^^^^^^^^^^^^^^
Not needed
Also you assign the return value from malloc to the input argument, i.e. you "destroy" the input.
Further, you never copy the value of the input string to the allocated memory.
Instead of the above, you need:
char* res = malloc(strlen(str) + 1);
if (res != NULL)
{
strcpy(res, str);
}
return res;
There are two areas of memory, the stack where local things exist, and the heap where other things exist. The stack is automatic in that your compiler manages it for you, and the heap is something that you have to manage through calls to malloc, realloc, and free, etc.
Things that are known at compile can exist in the stack, whereas things that you don't know at compile time can exist in the heap and be allocated, reallocated, freed, etc., with calls to malloc, realloc, and free.
And that basically all comes down to the size of the memory allocated. If you declare, for example, an int, that int can change in value as your program executes because it always exists in a space that is the sizeof an int.
But you might want to place your string in the heap if it changes length while the program runs and you don't want to allocate something big enough to always be able to hold it. For example, you don't need to allocate space on the heap for str if you always made it big enough with something like char str[64] or something like that because you allocate that space ahead of time.
In terms of malloc, you ask it to allocate memory of a certain size, and if it can it returns a pointer to it, if it can't it returns NULL. So the variable that holds the pointer returned by malloc exists in the stack, and the memory allocated by malloc exists in the heap and is not automatic. Ie: when your program terminates the pointer variable in the stack is released but not the actual memory stored in the heap, so you have to free it with free.
In the case of sizeof, well, that tells malloc how much you want to allocate, in this case a char, but it can be anything that can be resolved to a size, for example a structure that you define, etc. So what you're basically saying when you call malloc is "give me something this big and give me this many of them". In this case, "give me something as big as a char" and give me "strlen(str) + 1 of them".
And because the size of a character is always 1 byte and strlen returns a value of type size_t which malloc takes you can simply do it as char *ptr = malloc(strlen(str) + 1). But keep in mind that malloc returns a pointer of type void so you need to cast it to the type you are requesting. In this case you would cast it to a char* like this: ptr = (char*)malloc(strlen(str) + 1).
The other error is described in the other answer. But that is basically in a nutshell how malloc works. I'm not a teacher and I apologize if I'm not 100% clear.

Char Pointers and malloc

I was a bit confused with the concept of char pointers so I made a simple code just printing my name provided by user (me). I also wanted to practice malloc so I referenced the pointer to a certain memory in RAM, but I really didn't know what to put after "sizeof(char) *" because that is the user input, which is not yet decided.
Also, after doing that, I freed the memory, but I got an error message on command line saying:
*** Error in `./char': double free or corruption (fasttop): 0x00000000017fe030 ***
Aborted
It seems like I freed the same memory twice or something, but I don't know what to delete or add. Please help!
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings = malloc(sizeof(char) * 10);
printf("What is your name?\n");
//wait for use to type his/her name
strings = get_string();
printf("Hello %s\n", strings);
free (strings);
return 0;
}
The line strings = get_string(); actually assigns the value returned by get_string() to strings. It doesn't write it into the memory you allocated.
So the value returne by malloc() has been overwritten (and lost in this case).
The free(strings) is releasing whatever get_string() returned. The question doesn't provide the code for that but presumably it isn't valid to free() it.
Because the run-time told you it was freed twice I'm guessing you have allocated memory in get_string() then freed it and returned an invalid pointer.
If you want to use the memory you allocated you need to change get_string() to accept a pointer:
void get_string(char *str){
//Do whatever writing you value into str[] as an array of char..
}
Good practice would have:
void get_string(char *str, size_t max){
//Do whatever writing you value into str[] as an array of char..
//Use max to avoid writing beyond the end of the space allocated...
}
Then call as get_string(strings,10);.
EDIT: After a bit of research the flaw has been identified. get_string() doesn't directly free() the string it returns but adds it to a list of allocations made by the library which are freed on exit (in a function called teardown() registered with atexit() or other compiler dependent features).
That is poor design because consumer code is provided no safe way of itself freeing the memory which in a typical use case will not be required for the whole application execution. get_double() is worse because it never returns the allocated data but never reuses it and amounts to a straight memory leak.
The code should either:
Conform to the documentation and require consumer code to free() the string (maybe rename it as say get_string_alloc() for clarity).
Offer a library routine to free the string (get_new_string() and release_string())
There is no very nice way to shift ownership of allocated memory in C but holding onto it for the remainder of execution is definitely not the answer.
Many libraries go round the houses to push allocation onto consumer code but that is onerous when the full size of the space required can't be known such as here.
I'd suggest putting _alloc() at the end of any function that returns objects that consumer code must later free().
So the answer for the question posed is remove the malloc() and the free() because the library handles both. However beware if your program makes many calls to that function and others that internally rely on it (like get_double()) you may run out of memory because the library is sitting on dead space.
The problem is your get_strings overrides your initial malloc. A pointer value is a value. By equating it with something else, you replaced your malloc value.
Memory is allocated at the statement:
strings = get_string();
You dont have to malloc it ( char *strings = malloc(sizeof(char) * 10);
)
Without malloc it will work fine
First You have created a dynamic memory which will be pointed by *strings. But then you are pointing to the local string (from get_string() function) using *strings pointer. when you call free, program is trying delete local (stack) reference and throwing error.
To solve that error, the program should be
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings = malloc(sizeof(char) * 10);
printf("What is your name?\n");
//wait for use to type his/her name
strcpy(strings, get_string()); // Use strcpy instead of assigning
printf("Hello %s\n", strings);
free (strings);
return 0;
}
You don't include the code for get_string(), but you're overwriting strings with its return value which is wrong. The address you pass to free() must come from malloc(), and it seems you're violating that (in addition to losing the original returned address for your 10 bytes).
Assuming get_string() returns static storage (i.e. you don't need to free it) you can do this without involving malloc().
If you really want to, something like this might work:
printf("What is your name?\n");
const char *name = get_string();
const size_t nlen = strlen(name);
char * const name_copy = malloc(nlen + 1);
if(name_copy != NULL)
{
memcpy(name_copy, name, nlen + 1);
printf("Hello %s (from my own memory!)\n", name_copy);
free(name_copy);
}
This is rather convoluted but you get the idea.
char *strings;
No need for new malloc as string returned from get_string() function is already on the heap, you just need to pick up pointer to first character. (get_string() function reference)
strings = get_string();
printf("Hello %s\n", strings);
After printing string you should free memory allocated for it, as it is stated in get_string() function reference
Stores string on heap (via malloc); memory must be freed by caller to
avoid leak.
I think everything else is fine, try this code:
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings;
printf("What is your name?\n");
//wait for use to type his/her name
strings = get_string();
printf("Hello %s\n", strings);
free (strings);
return 0;
}

Free function fails

I am writing a simple program in Linux. Its purpose is to display the GNU version number. But it seems the free() function screams at me. When I execute the program. It shows the following:
* Error in `./a.out': munmap_chunk(): invalid pointer: 0x00007fa89f028d8a *
and Backtrace and memory map.
Below is my code:
# include <stdio.h>
# include <gnu/libc-version.h>
# include <string.h>
# include <stdlib.h>
int main(void){
const char *s;
s = (const char *)malloc(16*sizeof(char));
s = gnu_get_libc_version();
printf("%s\n",s);
free((char *)s);
return 0;
}
You have lost the pointer returned by malloc the moment you reinitialized s with the return value of gnu_get_libc_version. You are now trying to free the pointer returned by gnu_get_libc_version which has not been allocated by malloc.
You need not malloc before calling gnu_get_libc_version and do not need to free after calling it.
s = gnu_get_libc_version();
This does not do what you seem to think it does. It looks like you expect it to populate the memory you've allocated previously, memory that is pointed to by s.
What it actually does is cause s to point somewhere totally different, somewhere that is decided by the function gnu_get_libc_version.
Given the free error and the example usage in the documentation, there's a better-than-even chance this memory is not allocated from the heap, hence attempting to free it will cause undefined behaviour.
Assuming that gnu_get_libc_version does actually return the address of a C-style string and it's not from the heap (and this certainly appears to be the case base on the link above), you don't need to allocate the memory for it. Instead you can just have:
int main(void) {
const char *s = gnu_get_libc_version();
printf("%s\n", s);
return 0;
}
or even the shorter (using puts and the return value directly):
int main(void) {
puts(gnu_get_libc_version());
return 0;
}
If you do want to get the version information into your own allocated buffer (and assuming you have enough memory for it), you can use:
int main(void){
const char *s = malloc(16);
strcpy(s, gnu_get_libc_version());
printf("%s\n", s); // or puts(s)
free(s);
return 0;
}
This copies the string (from the area returned from gnu_get_libc_version) into your own buffer, rather than changing s to point somewhere else.
Notice that I've changed some other things in your original code. The first is to remove the explicit cast of the malloc return value. This is something that should not be done in C as it can hide certain subtle errors. C is perfectly capable of implicitly casting the void * return value to another pointer type.
The second is the cast in free which is also unnecessary for the same reason.
The third and final change is to remove the multiplication by sizeof(char). This value is guaranteed by the standard to be 1 so there's no technical reason why it's needed.
This function gnu_get_libc_version() probably returns a pointer to static memory.
In this line
s = gnu_get_libc_version();
you reassign the s to an other char * which return by gnu_get_libc_version. As the former value of s, which was allocated by malloc, is lost, which results a memory leak. And the char * return by gnu_get_libc_version wasn't allocated by malloc, so when you call free on a pointer which not returned by malloc, some error occurs.
s = gnu_get_libc_version();

Efficient/easy way to guard for NULL after conversion from "char x[n]" to "char* x"?

I have recently made changes in some code that makes a char name field dynamic.
So it was originally like
struct boo
{
char name[100];
...
}
and i have changed it to
struct boo
{
char *name;
...
}
so this make name dynamically allocate the amount of memory actually needed to store the names.
Anyway.. the result of this change will require me to add if(boo->name) null pointer check in about 1000 places in the code.
So just wondering is there any smart or efficient way (reduce programmer development time) of doing this null pointer check.
It will be far easier to ensure that the buffer is allocated when the structure is created rather than checking it wherever the structure is used. Don't ever let it be NULL in the first place!
If you need a pointer value to place in the structure before you have the relevant data, you can keep a global empty string to use specifically for this task. Compare to this pointer before trying to free the memory.
If this is C++ and not C, seriously consider using a std::string instead of a pointer.
if (name) works, but there is always the problem that your pointer may not be initialized to NULL to start with.
if you are dynamically allocating your structs, to make sure this happens, do:
mystruct foo = calloc(sizeof(foo));
calloc zeroes the memory.
EDIT:
In addition, if you only want to check for name in debug builds, you can do:
assert(name);
This will quit the program right at that line if name is NULL but be optimized out to nothing in "release" builds.
Your problem is to check the return allocation succeeds when you malloc.
Some people like to use the xmalloc wrapper to malloc from libiberty library:
— Replacement: void* xmalloc (size_t)
Allocate memory without fail. If malloc fails, this will print a message to stderr (using the name set by xmalloc_set_program_name, if any) and then call xexit. Note that it is therefore safe for a program to contain #define malloc xmalloc in its source.
http://gcc.gnu.org/onlinedocs/libiberty/Functions.html
You can also easily write your own xmalloc function:
void *xmalloc(size_t size)
{
char *p = malloc(size);
if (!p) {
fprintf(stderr, "Error: allocation failure\n");
exit(EXIT_FAILURE);
}
return p;
}

Resources