Can anyone help me, why I'm getting an error message while trying to free the allocated memory: Heap corruption detected. CTR detected the application wrote the memory after end of heap buffer.
char *ff (char *s){
char *s1 = new char [strlen(s)];
strcpy(s1, s);
return s1;
}
int _tmain(int argc, _TCHAR* argv[])
{
char *s = new char [5];
strcpy(s, "hello");
char *s2 = ff(s);
delete []s; // This works normal
delete []s2; // But I get an error on that line
return 0;
}
char *s = new char [5];
strcpy(s, "hello");
Causes Undefined behavior(UB).
You are writing beyond the bounds of allocated memery. You allocated enough memory for 5 characters but your string has 6 characters including the \0.
Once your program has caused this UB, all bets are off and any behavior is possible.
You need:
char *s = new char [strlen("hello") + 1];
In fact the ideal solution is to use std::string and not char *. These are precisley the mistakes which std::string avoids. And there is no real need of using char * instead of std::string in your example.
With std::string:
You don't need to new anything
You don't need to delete anything &
You can do everything with std::string, that you do with char *.
new char [strlen(s)]; does not count the closing \0 character, so your buffer is too short by one character.
strcpy includes the null terminator; strlen does not. Write:
char *s1 = new char [strlen(s) + 1];
From man strcpy(3):
The strcpy() function copies the string pointed to by src,
including the terminating null byte ('\0'), to the buffer pointed to
by dest.
So you need to reserve 6 bytes 5 for the string and 1 for the NULL byte
char *s = new char [6];
strcpy(s, "hello");
All answers so far have addressed either the first or the second allocation. To sum up, there are two changes you must make:
char *s1 = new char [strlen(s) + 1];
...
char *s = new char [5 + 1];
In both cases, you must allocate enough space for the string plus one byte for the terminating '\0'.
As others already pointed out, with c++ it's easier and safer to use std::string. No fuss with allocation and release of memory or paying attention to '\0' bytes:
std::string ff (const std::string &s){
std::string s1(s);
// do something else with s1
return s1;
}
int main(int argc, char* argv[])
{
std::string s("hello");
std::string s2 = ff(s);
return 0;
}
and if it's just copying the string:
std::string s("hello");
std::string s2(s);
You need to specify char *s1 = new char [strlen(s) + 1]; to make room for the '\0' which terminates the string.
You've corrupted s2 pointer by
strcpy(s, "hello");
Because s has size 5, while you've missed that strcpy includes string terminator.
Your initial string s is only five characters long so can't be null terminated. "hello" will be copied by strcpy including the null-terminator but you'll have overrun the buffer. The strlen needs it to be null terminated so if the null's not there, you'll have problems. Try changing this line:
char *s = new char [6];
Better still, prefer std::string to C style string functions - they're just as efficient and a lot safer and easier to use. Also, try to avoid new and delete unless you really have to use them. The problems you're getting are very common and can easily be avoided.
Related
I am trying to copy a char* and char symbol into a new char* , however the desired result after copying is wrong.
char* name = "someData";
char symbol ='!';
int size1 = strlen(name);
int size2 = 1;
int newSize = size1 + size2 + 1;
char* res = new char[newSize];
strcpy(res,name);
const char* symbolPointer = &symbol;
strcat(res, symbolPointer);
cout<<*res;
I expect the result to be "someData!" , however it is only "s" , where is my mistake?
char* name = "someData";
This is an ill-formed conversion in C++ (since C++11). I recommend to not point to string literals with pointer to non-const.
const char* symbolPointer = &symbol;
strcat(res, symbolPointer);
Both arguments of std::strcat must be null terminated. symbolPointer is not a pointer to a null terminated string. Because the pre-condition of std::strcat is violated, the behaviour of the program is undefined.
cout<<*res;
res is a pointer to the first character of the string. By indirecting through the pointer to first character, you get the first character. That is why you see the first character (in case the undefined behaviour hasn't caused the program to do something completely different).
Lastly, the program leaks the allocated res.
Here is a fixed example:
std::string name = "someData";
name += '!';
std::cout << name;
The problem is the following:
cout<<*res;
This is equivalent to:
cout << res[0];
It prints just the first character of the output. Use
cout<<res;
Try it this way:
const string name = "someData";
const char symbol ='!';
string res = name + symbol;
cout << res;
You should avoid the legacy C nul-terminated string handling functions. You should avoid using new directly in your code.
The observed result you are asking about is due to you writing *res (a single character) instead of res (a pointer to the first character) in the output statement. But the code was buggy besides that, as strcat will copy until it finds the terminator, so it will overwrite some unknown amount of memory beyond what you allocated.
symbolPointer should end with null character, because strcat requires 0-terminated string.
So if you want to continue on your way,
(not a good idea but)
You can add this before strcat.
*(symbolPointer+1) = 0;
#include <iostream>
#include <cstring>
int main() {
char name[] = "someData";
char symbol ='!';
int size1 = strlen(name);
int size2 = 1;
int newSize = size1 + size2 + 1;
char* res = new char[newSize];
strcpy(res,name);
char* symbolPointer = &symbol;
*(symbolPointer + 1) = 0;
strcat(res, symbolPointer);
cout<<res;
return 0;
}
I'm trying to make my own string class, and I'm trying to create the constructor. So far I'm having a little struggle.
I have my function prototypes defined in a header file and the variable buffer defined in the header file like this char *buffer;, in a new cpp file I'm trying to define the constructor like this:
mystring::mystring(const char *s)
{
int counter = strlen(s)+1;
*buffer = generate_c_array(counter);
}
char * mystring::generate_c_array(int size)
{
return new char[size];
}
I'm basically trying to make it such that buffer is a char array of size s+1 and contains the contents of s followed by a null terminator. Though, this is causing my program to crash.
I'm not sure how to assign buffer correctly, does this look correct?
You can simply write your code
mystring::mystring(const char *s)
{
sz = strlen(s) // sz- another data member, holds size
buffer = new char[sz + 1];
strcpy(buffer, s); // assuming s is null-terminated
}
The for loop and counter were not necessary, in fact
You assign to the specific character in the buffer, not to the variable buffer. Change to:
buffer = generate_c_array(counter);
Other than that, strdup will do the same job for you, but you will have to deallocate with free(). In current code you actually don't really copy, you will have to do strcpy(buffer, s) unless using the strdup mentioned earlier.
Why are you looping over length of the string s?
If you need length of the string use it directly:
std::size_t length = strlen(s);
buffer = generate_c_array(length + 1);
// Copy your string:
memcpy(buffer, s, length)
// Add the terminator character:
buffer[length] = '\0';
You haven't copied the content..
If you want to assign a pointer ( which is what new give you ) to another pointer, you don't need *.
strncpy do the copying for you.
mystring::mystring(const char *s)
{
int counter = strlen(s)+1;
char* buffer = generate_c_array(counter);
strncpy(buffer, s, counter);
}
char * mystring::generate_c_array(int size)
{
return new char[size];
}
I wrote a function which receives as a parameter a char pointer,then builds a new dynamic allocated char array that contains that parameter char.Then,it returns the new char array.
This is the function:
char* read_string(char *pstr)
{
char *str;
str = new char[strlen(pstr)];//allocate memory for the new char
str[strlen(pstr)] = '\0';
for(unsigned i=0;i<strlen(pstr);i++)//build the new char
str[i]=pstr[i];
return str;//then return it
}
In main I have:
int main()
{
char *Pchar = read_string("Test");
cout<<Pchar;// Outputs "Test"
delete [] Pchar;//"Program received signal SIGTRAP, Trace/breakpoint trap." error
}
I declare a char pointer in main and then make it point to the char array that is returned from the read_string function.It outputs what I want but if I want to free the memory it gives me runtime error.How can I free up the memory if I don't need to use Pchar anymore?
EDIT:Thank you all for your very informative answers.I have successfully resolved the problem.
You need to allocate more memory to have space for EOS character:
str = new char[strlen(pstr)+1];
Your specific problem is an off-by-one error:
str = new char[strlen(pstr) + 1];
// ^^^^ need one more for the '\0'
str[strlen(pstr)] = '\0';
Generally, since this is C++ and not C, it would be better to return a smart pointer so the caller knows what the ownership semantics of the pointer are:
std::unique_ptr<char[]> read_string(char *pstr)
{
std::unique_ptr<char[]> str(new char[strlen(pstr) + 1]);
// rest as before
return str;
}
It seems that the error occurs due to incorrect length of the allocated string.
You have to use the following record to allocate the string
str = new char[strlen(pstr) + 1];//allocate memory for the new char
str[strlen(pstr)] = '\0';
The function can look the following way
char* read_string( const char *pstr )
{
char *str;
size_t n = strlen( pstr );
str = new char[n + 1];//allocate memory for the new char
strcpy( str, pstr );
return str;
}
Hi guys I'm writing a program that reads NMEA sentences for a university assignment and I'm having trouble with segmentation fault. Can anyone help me fix it, please?
NmeaSentence::NmeaSentence(std::string sentence) {
const char *temp = sentence.c_str();
char *c_sent;
strcpy(c_sent, temp);
char *pch;
for(int i = 0; i < MAX_SENTENCE_PARTS; i++){
pch = strtok(c_sent, ",");
this->sentenceParts[i] = pch;
}
this->sentence = sentence;
this->sentenceType = sentenceParts[0];
}
The error seems to be happening at strcpy. What am I doing wrong?
You don't allocate memory for c_sent. That's undefined behaviour.
Use char *c_sent = new char[sentence.size() + 1];. I've added space for the null terminator. Don't forget to call delete[] c_sent; before the function exits.
(By the way, temp is valid for the lifetime of sentence, unless it's modified in any way.).
The temporary string c_sent is uninitialized.
char * c_sent
to
char * c_sent = strdup(sentence.c_str());
Dont forget to free, before exit.
free(c_sent);
You won't need temp this way.
The member function has several defects.
If the parameter of the function is not changed then it would be better to declare the function as
NmeaSentence::NmeaSentence( const std::string & sentence);
As it was already said you did not allocate memory where you are going to copy sentence. Pointer c_sent was not initialized by the address of an allocated memory.
The second defect is that pch always points to the same address in c_sent because you are incorrectly using function strtok. You should use it the following way
char *pch = strtok(c_sent, ",");
for(int i = 0; i < MAX_SENTENCE_PARTS && pch; i++){
this->sentenceParts[i] = pch;
pch = strtok( NULL, ",");
}
Also it is not clear how you will determine how many parts the string contains.
Right off the bat, I'm required to use dynamically allocated character arrays for my assignment, so do NOT suggest I just use strings. I need to create a method that accepts a character array as an argument, and inserts that character into a char* using strcpy. How do I do this without first initializing the char*?
Here is my code so far:
char* char_array;
char test_array[] = {'t','e','s','t','\0'};
strcpy(char_array, test_array);
Your char_array is just an unitialized pointer. You need to dynamically allocate memory for it and then carry out strcpy.
char* char_array = new char[6];
char test_array[] = {'t','e','s','t','\0'};
strcpy(char_array, test_array);
Or as suggested by Joachim you can use strdup() to duplicate a string - it will allocate the memory and copy the string into it.
In both cases, don't forget to free() (or delete[]) the resulting memory once you're done with it.
You can't do that unless you actually allocate a chunk of memory for char_array through malloc or new.
int length = 6;
char* char_array = (char*) malloc(sizeof(char) * length);
or
char* char_array = new char[6];
char * char_array = NULL;
void yourFunc(char your_array[]) {
if (NULL != char_array) {
free(char_array);
char_array = NULL;
}
char_array = (char *)malloc(sizeof(char) * strlen(your_array));
strcpy(char_array, your_array);
}
you stated you need a method/function that accepts a char[]/char *
you have stated your constraints ...
this does seem to be low level for instructional purpose
I assuming null terminated character array and valid source character array
//function accepts character array
char * charseqduplicate(char * s)
{
//low level c
const int len = strlen(s) + 1;;
char * copy = new char[len];
strcpy(copy, s);
//remember to delete or use something like unique_ptr
return copy;
}
void letsdothis()
{
//low level c
char test[] = {'y','e','s',char(0)};
char * dup = charseqduplicate(test);
cout << dup;
delete [] dup;
}