+ 10

I have some doubts regarding efficient memory management. Please help me

Hi ! These days I'm trying to understand how to efficiently manage heap-memory in C++ and how to tackle memory faults/leaks. I've added comments to help you to get what I'm doing and understand my problem better. So, I've this simple code inside main() function: ------------------------------------------------------------------------------------------------------------- char* str = new char; // allocating memory from heap for(unsigned long int i = 0; i < 1000; i++) *(str + i) = '#'; // as heap-memory is writable, so this should be okay delete str; // de-allocating the memory because it was allocated using new str = NULL; // preventing str from becoming a dangling pointer return 0; ------------------------------------------------------------------------------------------------------------- Let me know what I'm doing illegal for which my code terminates abnormally ( with a status of -1073741819, 0xC0000005 ). Also, provide a better approach to work with pointers and heap-memory. Thanks for your help! Side note: I'm using Code::blocks gnu gcc compiler, following the -std=c++11 language standards.

29th Mar 2019, 7:42 AM
777
777 - avatar
16 odpowiedzi
+ 12
Hello! You allocated memory for a char, not a char array , this is the right way size_t y = 10; char *x = new char[y]; you may use int but I prefer size_t
29th Mar 2019, 8:58 AM
AZTECCO
AZTECCO - avatar
+ 14
In the first line of your code you are declaring a pointer to char, which is ok, but then allocating the memory for a single char type dynamic variable. So inside the for loop you are trying to access to a part of memory adjacent to where str points wich is not declared to be of the type you need. You should be able to correct the thing just by allocating the right amount of memory you need: const int size = 1000; char *str = new char[size]; Remember that to deallocate a dynamic array you have to use the delete[] command
29th Mar 2019, 9:00 AM
Andrea Leoni
Andrea Leoni - avatar
+ 10
You are correct, but remember that you're allocating an array, if you allocate just a 1 byte variable and than try to access the memory adjacent to the block you allocated (like with *(str+1) ) you are doing something illegal. :3 edit: i said "illegal" because I wanted to emphasise on the "better to not do it" but it's actually just a really unsafe practice.
29th Mar 2019, 9:51 AM
Andrea Leoni
Andrea Leoni - avatar
+ 9
Adding to AZTECCO 's answer, to delete a block of memory allocated by new[] (This is the operator that accepts a size, denoting the number of objects to allocate), use delete[] followed by the pointer name. In your case, the allocation and deallocation statements become: size_t size = 1000; char* str = new char[size]; // Allocates entire block for str. // Use str. delete[] str; //Deallocates the entire block rather than just a single cell. So in the end, always: Deallocate memory allocated by new using delete. Deallocate memory allocated by new [] using delete[].
29th Mar 2019, 9:07 AM
Solo Wanderer 4315
Solo Wanderer 4315 - avatar
+ 7
rv7 theoretically you can access everything.. char* x = &something; cout<<*(x+999999); You are accessing a memory address 9999999 far away from x but it has nothing to do whit x, x holds just an address to a single char . C language left these things called undefined behaviors , in short the syntax is correct but not the behaviour, that's why c and C++ are not very simple
29th Mar 2019, 10:17 AM
AZTECCO
AZTECCO - avatar
+ 7
No way , it relies on proper designs only.. What does it means? A pointer stores only an address. A pointer is of a type but this doesn't mean the address contains this type. That said the programmer has to manage things, designs are consolidated structure of tasks management, something like how-to's. I said designs but also idioms matters, for example Kinshuk Vasisht rule is very common in programming.. So in the end the c++ way is to make a class do the job right, and here we go to Dennis std::string or smart pointers.. For now I suggest you to test and dig plain arrays tricks , after you'll go for STL standard template library
29th Mar 2019, 10:54 AM
AZTECCO
AZTECCO - avatar
+ 6
Also want to add that if you're using char arrays in C++ you'd probably be better off changing to an std::string. This way you don't have to deal with deallocation, thus limiting your memory leaks. For data types other than char's you can use std::unique_ptr's or std::shared_ptr's. ( not that you can't use it with char ) These manage the resource for you and call the correct delete on it automatically when they go out of scope, even when something throws. https://en.cppreference.com/w/cpp/string/basic_string https://en.cppreference.com/w/cpp/memory/unique_ptr https://en.cppreference.com/w/cpp/memory/shared_ptr
29th Mar 2019, 9:39 AM
Dennis
Dennis - avatar
+ 6
char str []="Sololearn"; Do the job for you, it's a C string. This way you allocate memory correctly. You can access like you told *(str + i) but if you go out of bounds it's undefined behaviour because you are accessing an unallocated memory ! You may iterate your array until you encounter a null char \n for (int i=0 ; str[i] != '\n' ; ++i) {..... Hope it helps
29th Mar 2019, 10:05 AM
AZTECCO
AZTECCO - avatar
+ 6
The reason why array access out of bounds is not invalid is because if you enforce checks on sizes, then the program slows down. Further, a C array does not maintain its size and so checking for bounds is an even more expensive operation. This is also the reason why some STL containers provide an 'at' method even when they have the [] operator overloaded. This is because the [] operator is not guaranteed for exception safety, and so may be free of bound checks. So you can pass any index. But the 'at' method is safer to use as it throws an exception when the index is out of bounds. As for why the memory is illegal to access, the reason is that the memory was never your program's to begin with. What new does is request the OS of your machine to allocate some memory. This memory will not be accessed by other programs and the OS itself for storage purposes. So if you try to access memory outside the reserved limit, you are basically manipulating data having no meaning to you. But this can have adverse effects.
29th Mar 2019, 11:21 AM
Solo Wanderer 4315
Solo Wanderer 4315 - avatar
+ 5
Very well explained Kinshuk Vasisht 👍
29th Mar 2019, 9:31 AM
AZTECCO
AZTECCO - avatar
+ 5
I appreciate your answer guys! And, one last thing, I want your feedback to check if I'm correct or not with my following concept: char* str = new char; // declares a pointer to 1 byte memory in the heap *str // de-references the pointer to get the value at that location *(str + 1) // denotes the value at the next 1 byte address *(str + 2) // denotes the value at the next to next address Similarly, *(str + i) denotes the value at the next ith location And, we know that heap-memory is writable, then *(str + i) = '#' should work. Now, let length = 10, so basically I'm trying to create a string of length 9 (and '\0') whose first character's location will be stored in "str", like below ------------------------------------------------------------------------------------------------- str --- | V { 'S' , 'o' , 'l' , 'o' , 'L' , 'e' , 'a' , 'r' , 'n' , '\0' } i = 0 ............................................................. i = 9 ------------------------------------------------------------------------------------------------- EDIT:: This concept works only for small strings of length < 500, like in these images: https://www.dropbox.com/s/oohsujl4j6yq44q/Segfault_output2.JPG?raw=1 https://www.dropbox.com/s/y0bjxzwnz4xbf28/Segfault_output.JPG?raw=1 (the execution time includes time spent in input)
29th Mar 2019, 9:44 AM
777
777 - avatar
+ 4
@Andrea yes, this is what I'm confused in: "...memory adjacent to the block you allocated..." - how is this illegal?
29th Mar 2019, 9:59 AM
777
777 - avatar
+ 4
@AZTECCO, haha... So, to be on a safe side, I should say, "pointers" are like chameleons. Finally, there is one thing I'd like to know: is there any way to check if an address is un-allocated or not?
29th Mar 2019, 10:32 AM
777
777 - avatar
+ 3
So.. welcome to UB bro :) lol
29th Mar 2019, 10:18 AM
AZTECCO
AZTECCO - avatar
0
it’s cool
29th Mar 2019, 4:57 PM
Igor The Golden Fish
Igor The Golden Fish - avatar
0
i will help you
30th Mar 2019, 8:26 PM
Jaedon Person
Jaedon Person - avatar