This question already has answers here:
C++ management of strings allocated by a literal
(4 answers)
Closed 8 years ago.
I have tough problems while trying to de-allocate this pointer.
I'm having this error:
error for object 0x10007fd20: pointer being freed was not allocated
I have the following structure:
char * doSomething() //I cannot change this method.
{
return "hello world";
};
int main ()
{
char * var= doSomething();
cout<< var<<endl;
delete[] var;
};
Please consider that I cannot use string, because I'm not being provided with the doSomething method. As I'm using it a lot.. after a while the app collapses because of the RAM memory use.
You are trying to delete[] a static string. You only want to delete[] objects you have created with new[].
You can delete only what was allocated using the corresponding operator new. String literals have static storage duration. They are not dynamically allocated. According to the C++ Standard
8 Ordinary string literals and UTF-8 string literals are also referred
to as narrow string literals. A narrow string literal has type “array
of n const char”, where n is the size of the string as defined below,
and has static storage duration (3.7).
I see multiple potential issues:
you are using delete[] on a string literal, wrong, and that's why you are getting the error
you are converting a string literal to a char*, which is deprecated and insecure (since you can't modify a string literal)
you are returning a pointer to a local variable, in your situation this is allowed because you are working with string literals but in general
int *function() { int x = 10; return &x; }
Should never be done, if you return a pointer to something in a function, be sure it is dynamically allocated or statically allocated but not allocated on stack.
In my belief, string literals like "Hello world" is stored in the static section of your program instead of on the stack. That means, there is only one copy of "Hello world" in the memory, no matter how many times you call the function. And those calls should return just the same address. The RAM problem of your program is not caused by this issue.
Related
I have very basic question. In the below code we are passing string as argument to someFunc function where it takes char array as argument. How will memory get allocated for a[], and where will the memory get allocated ? Also how it will be decided how much memory to allocate in case of different sized strings ?
int someFunc(char a[])
{
//do something
}
int main( )
{
someFunc("Frankenstein is dead");
someFunc("Hello there");
return 0;
}
When declaring an argument as an array in C++, it's actually declared as a pointer.
That is, your function is really
someFunc(char* a) { ... }
That means, what is passed is a pointer to the first element of the literal strings.
Also note that in C++ a literal string is an array of constant characters. So it decays to the type const char*. Which means your argument have to be of that type as well.
How the constant string literal arrays are allocated are really irrelevant and an implementation detail, but it's typically the compiler saves the strings together with the generated code in the executable program file. This lets them be loaded into memory by the operating system program loader together with the code, and no "dynamic" allocation for the strings themselves are made.
This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
What is the difference between char s[] and char *s?
(14 answers)
Closed 5 years ago.
char *char_ptr = "anisha";
char char_arr[]= "anisha";
What is the "reason" that the contents of first memory location cannot be modified but the contents of second memory can?
Why is the first memory storage a constant string whereas the second one isn't?
For C++
Because pointer and array are different things.
For the 1st case, char_ptr is a pointer points to a string literal, whose contents can't be modified. And trying to modify them via the pointer is UB. (That's why from C++11 we have to write it as const char *char_ptr = "anisha";.)
Attempting to modify a string literal results in undefined behavior: they may be stored in read-only storage (such as .rodata) or combined with other string literals:
For the 2nd case, char_arr is an array, whose contents are copied from the string literal. The contents is owned by the array itself and then it's fine to be modified.
String literals can be used to initialize character arrays. If an array is initialized like char str[] = "foo";, str will contain a copy of the string "foo".
First is a stack-allocated pointer to the first item at array of chars allocated at some immutable storage for the string literal. Pointer itself is mutable, but the data it points to is not.
Second is a stack-allocated array of 7 chars that is only initialized with data from string literal. Whole array is mutable because it is allocated on the stack.
Because the first one is a string literal whose address you are assigning. And string literals are non modifiable. Though it looks similar to the second case it isnn't. The string literal which is an array decays into pointer which is assigned to the char*.
Second one is simply initializing a local char array. Here it is just initializing the element of the array with that of string literal. And this is modifiable.
char char_arr[]= {'a','n','i','s','h','a','\0'};
And this is modifiable as a normal char array can be.
From C11 standard 6.4.5p7
It is unspecified whether these arrays are distinct provided their
elements have the appropriate values. If the program attempts to
modify such an array, the behavior is undefined.
This question already has answers here:
Modifying String Literal [duplicate]
(4 answers)
Closed 9 years ago.
I am getting a segmentation fault while running the following code :-
char *p ="Hello";
*p = 'M';
what I intended was to replace the first character of the string "Hello" with 'M'. But I'm getting segmentation fault. What could be the reason?
It's undefined behaviour. For compatibility with old C code, C++ compilers have let you point a non-const pointer at a string literal (e.g. your "Hello"), but you can not write through them portably.
It's best to use:
const char* p = "Hello"; // if you really need a pointer, probably so you
// can move it within the text, point it at other
// text, set it to a NULL sentinel after use...
const char[] hello = "Hello"; // if you're really only interested in the text
Any string literal in C++ and C (for example "Hello" in your code) is of type const char [6] and can implicitly be assigned to any const char * value:
const char * str="Hello";
indicating that it resides in memory marked as read-only by the operating system (you should have gotten a compiler warning). Therefore an exception will be thrown when you try to change that memory location.
The reason why the compiler puts this in read-only memory is because you may be using another identical (or even similar) string literal "Hello" in a different part of your code. By marking the memory location of the string literal as read-only, the compiler only needs to store the string literal once in memory.
Note also, that the C++ standard does not require the compiler putting the string literal into read-only memory, it just says that modifying a string literal is undefined behaviour. In practice however, a string literal is stored in read-only memory on any modern operating system or compiler.
The compiler is putting the string for "Hello" into a read-only memory segment and giving you a pointer to it. The fact that you're allowed to assign the pointer to a char* is done for backwards compatibility. C++ states that it's undefined behaviour.
If you want to alter the string then declare it like this :
char p[]="Hello";
My understanding is that in C and C++, creating a character array by calling:
char *s = "hello";
actually creates two objects: a read-only character array that is created in static space, meaning that it lives for the entire duration of the program, and a pointer to that memory. The pointer is a local variable to its scope then dies.
My question is what happens to the array when the pointer dies? If I execute the code above inside a function, does this mean I have a memory leak after I exit the function?
it lives for the entire duration of the program
Exactly, formally it has static storage duration.
what happens to the array when the pointer dies?
Nothing.
If I execute the code above inside a function, does this mean I have a memory leak after I exit the function?
No, because of (1). (The array is only "freed" when the program exits.)
No, there is no leak.
The literal string is stored in the program's data section, which is typically loaded into a read-only memory page. All equivalent string literals will typically point to the same memory location -- it's a singleton, of sorts.
char const *a = "hello";
char const *b = "hello";
printf("%p %p\n", a, b);
This should display identical values for the two pointers, and successive calls to the same function should print the same values too.
(Note that you should declare such variables as char const * -- pointer to constant character -- since the data is shared. Modifying a string literal via a pointer is undefined behavior. At best you will crash your program if the memory page is read-only, and at worst you will change the value of every occurrence of that string literal in the entire program.)
const char* s = "Hello"; is part of the code (program) - hence a constant never altered (unless you have some nasty mechanism altering code at runtime)
My question is what happens to the array when the pointer dies? If I
execute the code above inside a function, does this mean I have a
memory leak after I exit the function?
No there will be no memory leak and nothing happens to the array when the pointer dies.
A memory leak could be possible only with dynamic allocation, via malloc(). When you're malloc() something, you have to free() it later. If you don't, there will be a memory leak.
In your case, it's a "static allocation": the allocation and free of this memory space will be freed automatically and you don't have to handle that.
does this mean I have a memory leak after I exit the function?
No, there is no memory leak, string literals have static duration and will be freed when the program is done. Quote from the C++ draft standard section 2.14.5 String literals subsection 8:
Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration
Section 3.7.1 Static storage duration says:
[...] The storage for these entities shall last for the duration of the program
Note in C++, this line:
char *s = "hello";
uses a deprecated conversion see C++ warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] for more details.
The correct way would be as follows:
const char *s = "hello";
you only have to free if you use malloc or new
EDIT:
char* string = "a string"; memory allocation is static, and not good practice (if it will be constant the declaration should be a const char*)
because this is in the stack when the function ends it should be destroyed along with the rest of the local variables and arguments.
you need to use specific malloc/free and new/delete when you allocate the memory for your variable like:
char *string = new char[64]; --> delete string;
char *string = malloc(sizeof(char) * 64); --> free(string); //this is not best practice unless you have to use C
So, I'm wanting to get a better grasp on how string literals in C++ work. I'm mostly concerned with situations where you're assigning the address of a string literal to a pointer, and passing it around. For example:
char* advice = "Don't stick your hands in the toaster.";
Now lets say I just pass this string around by copying pointers for the duration of the program. Sure, it's probably not a good idea, but I'm curious what would actually be going on behind the scenes.
For another example, let's say we make a function that returns a string literal:
char* foo()
{
// function does does stuff
return "Yikes!"; // somebody's feeble attempt at an error message
}
Now lets say this function is called very often, and the string literal is only used about half the time it's called:
// situation #1: it's just randomly called without heed to the return value
foo();
// situation #2: the returned string is kept and used for who knows how long
char* retVal = foo();
In the first situation, what's actually happening? Is the string just created but not used, and never deallocated?
In the second situation, is the string going to be maintained as long as the user finds need for it? What happens when it isn't needed anymore... will that memory be freed up then (assuming nothing points to that space anymore)?
Don't get me wrong, I'm not planning on using string literals like this. I'm planning on using a container to keep my strings in check (probably std::string). I'm mostly just wanting to know if these situations could cause problems either for memory management or corrupted data.
String-literals have the type const char[N] (where N is the length + 1) and are statically allocated. You need not worry about memory issues; if a string is used in your program it is all handled for you, and resides somewhere in program memory (usually read-only).
That is, these are "the same":
static const char str[] = "a string";
"a string"
When you point to a string literal, you are pointing to the first character at the array. In fact, because the type is const char[], it's only safe to point to it via const char*. The conversion from string literal to char* is deprecated, and unsafe.
// the "same"
static const char str[] = "a string";
const char* strPtr = str; // decays
const char* s1 = "a string";
char* s2 = "a string"; // allowed, implicit const_cast
*s1 = 'A'; // not allowed, it's const
*s2 = 'B'; // allowed, it's not const (but leads to undefined behavior)
Firstly, declare the return value of foo as const, because string literals are constants that can't be changed without causing the dreaded "undefined behaviour". This will then force any pointers which use the return value of foo to also be declared as const, and potentially limiting the damage which can be (usually unintentionally) done. String literals are stored in the 'text' area of a binary executable - they're not created as such at run time.