C++ char* problems [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
#include<iostream>
using namespace std;
int main()
{
char *name="Siva",*str;
for(int i=0;i<strlen(name);i++)
{
str[i]=name[i];
}
cout<<str;
return 0;
}
The first program gives output Sivaœ> i.e siva with some garbage values....
But the second program show segmentation fault...Please help me to find out
exact answer...
#include<iostream>
using namespace std;
int main()
{
int i=0;
char *name="Siva",*str;
for(i=0;i<strlen(name);i++)
{
str[i]=name[i];
}
cout<<str;
return 0;
}

char *name="Siva",*str;
for(int i=0;i<strlen(name);i++)
{
str[i]=name[i];
}
str is a pointer, but it doesn't yet point to anything.
Since you're in C++, you should be using std::string:
#include<iostream>
#include <string>
using namespace std;
int main()
{
char *name="Siva";
std::string str;
for(int i=0;i<strlen(name);i++)
{
str += name[i];
}
cout<<str;
return 0;
}
Even better, get rid of the hand-written loop:
#include <algorithm>
int main()
{
char *name="Siva";
std::string str;
std::copy (name, name + strlen (name), std::back_inserter (str));
cout<<str;
return 0;
}
Better even still, there's no reason in this particular example why you need to do any of that at all:
char* name = "Silva";
std::string str = name;
cout << str;
By the way, string literals in C++ are inherently const:
const char* name = "Silva";
If you really must use a char*, first I would strongly question why, and then I would tell you to do this:
int main()
{
const char *name="Siva";
char* str = new char [strlen (name)+1]; // +1 for the null terminator
strcpy (name, str);
cout << str;
delete [] str;
return 0;
}
I would even more strongly question your need to copy it byte-by-byte:
int main()
{
const char *name="Siva";
char* str = new char [strlen (name)+1]; // +1 for the null terminator
for (size_t i = 0; i < strlen (name); ++i )
str [i] = name [i];
str [strlen (name)] = '\0';
cout << str;
delete [] str;
return 0;
}

You have undefined behaviour here:
str[i]=name[i];
str has not been initialized to anything. You are writing to places you shouldn't.

There are two problems with this.
The pointer str doesn't point to allocated memory, so writing through it is undefined behavior.
Even if it did point to valid memory, you're not writing the correct amount of data. When copying a string, you need to copy the 0 byte at the end which marks the end of the string; so the upper limit of your loop should bt strlen(name) + 1. Or you could use a library method like strdup() instead of your own for loop.
The reason the "working" version prints some garbage characters is that there's no 0 at the end of the copied string to tell iostreams to stop printing. The reason the "working" one doesn't crash, and the other one does, is pure dumb luck: the garbage in str, by chance, points to memory you're allowed to write to, while in the crashing program, it points to memory you're not allowed to write to. Simple as that.

It is because you have no memory allocated for str. (it will cause an undefined behavior)
You can mix that by using a merory allocation function like in this example :
#include<iostream>
using namespace std;
int main()
{
char *name="Siva",*str;
// Allocate memory with malloc
str = (char*)malloc( (strlen(name)+1) * sizeof(char) );
for(int i=0;i<strlen(name);i++)
{
str[i]=name[i];
}
str[strlen(name)] = 0;
cout<<str;
// Free the allocated memory
free(str);
return 0;
}
As you are using c++, you can do :
#include<iostream>
using namespace std;
int main()
{
char *name="Siva",*str;
// Allocate memory with new
str = new char[strlen(name) + 1];
for(int i=0;i<strlen(name);i++)
{
str[i]=name[i];
}
str[strlen(name)] = 0;
cout<<str;
// Free the allocated memory
delete []str;
return 0;
}
EDIT :
The reason you have some weird caracters at the end of your ouput is that because you string is not terminated with a '\0', it will continue to print it. (This will occur only if you don't have a segmentation fault )

There are a couple problems with your code.
Firstly, *str is not allocated, so it starts off by pointing to whatever bit of memory the pointer value happens to start off as.
Secondly, strlen() returns the length of the string excluding the terminating null character. So what you are doing is copying all the values of name into some random bit of memory, not terminating it, then telling the system to print that off, which could be any length.

str[i]=name[i]; is illegal, causes Undefined behavior, because you have not allocated memory for str.
Before for loop allocate memory for destination string str:
str = malloc (strlen(name) + 1 );
Also you forgetting string termination, after for-loop add terminate string str[i] = '\0';
Undefined behavior refers to computer code whose behavior is unpredictable.
You code should be:
char *name="Siva", *str;
str = malloc (strlen(name) + 1 ); // mistake
for(int i=0;i<strlen(name);i++)
{
str[i]=name[i];
}
str[i] = '\0'; // forgetting
To understand further you can read this answer: strcat() implementation works but causes a core dump at the end

Your problem is using char arrays and pointers to represent strings in language which has proper string type.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name = "Siva", str;
str = name;
cout << str;
return 0;
}

Problem is with str[i]=name[i] you must know that C++ does not care for memory leaks
as Java or some others. So you must allocate memory to a variable or pointer in order to avoid these problems. Already there are number of answers, you can also try
str=new char[strlen(name)+1];
and do not forget to terminate the char array with null when you done copy. In this case
str[strlen(name)]='\0';

Related

CRT Detected that the application wrote to memory after end of heap in C++

I have created a class of MyString. My code was working just fine but when I wrote the destructor for my class it is giving me the error at delete keyword. Please help me out where is the problem and what is the solution.
MyString Header File
#pragma once
#ifndef MYSTRING_H
#define MYSTRING_H
class MyString
{
private:
char* str;
int length;
public:
MyString();
MyString(const char*);
~MyString();
};
#endif
MyString CPP File
#include "MyString.h"
#include <iostream>
using namespace std;
MyString::MyString() {
length = 0;
str = new char[length];
str[length] = '\0';
}
MyString::MyString(const char* cString) {
length=strlen(cString);
str = new char[length];
for (int i = 0; i < length; i++)
str[i] = cString[i];
str[length] = '\0';
}
MyString::~MyString() {
delete[] str;
str = nullptr;
length = 0;
}
Main CPP File
#include "MyString.h"
#include <iostream>
using namespace std;
int main() {
//MyString s1;
MyString s2("OOP is Fun!!");
char name[15] = "Pakistan";
MyString s3(name);
return 0;
}
length = 0;
str = new char[length];
The Golden Rule Of Computer Programming states: "your computer always does exactly what you tell it to do instead of what you want it to do". Here, this is exactly what you told your computer: allocate an array with 0 bytes. In other words, an empty array that does not contain anything at all. In other words: absolutely nothing was allocated.
str[length] = '\0';
This sets the first byte in the array to 0. Since nothing was allocated, this is undefined behavior, and your memory corruption, right here. You should've allocated 1 byte instead of 0 bytes.
The other constructor has the same defect. Since '\0' is a plain char, no different than any other char, like 'A', or '0', your code must always allocate an extra character for it, in addition to all other characters in the actual text string.

Deletion of Dynamically Allocated Memory

I have been given a task, where I need to create the string_copy function Note that the function body and prototypes have been given by the source and that needs to be maintained. The portions written by me are after the comment write your code here.
#include <iostream>
using namespace std;
int string_length(const char* string_c);
char* string_copy(const char* string_c);
int main()
{
const char* string_c = "This is a string and is a long one so that we can create memory leaks when it is copied and not deleted";
// write your code here
int length = string_length(string_c);
cout << "Copied String: " << string_copy(string_c) << endl;
return 0;
}
int string_length(const char* string) {
int length = 0;
for (const char* ptr = string; *ptr != '\0'; ++ptr) {
++length;
}
return length;
}
char* string_copy(const char* string) {
// we need to add 1 because of ’\0’
char* result = new char[string_length(string) + 1];
// write your code here (remember zero-termination !)
int i;
for (i = 0; string[i] != '\0'; ++i)
{
result[i] = string[i];
}
result[i] = '\0';
return result;
}
Now task tells me
that it is very important that any memory allocated with e=new TYPE is
released later with delete e (and a=new TYPE[size] with delete [] a)
else this will lead to an error.
It is not exactly clear if error means compile/runtime error or error as in my task did not meet the requirement error.
My question is, in this code how do I delete the intermediate dynamically created result array? If I delete result, won't it fail the purpose of the task? Then how am I to respect the quotation above or maybe simulate memory leak as given in the long string constant?
Thanks.
EDIT: Why the negative votes? Please at least explain the reason! I am not asking any solution or something, but mere suggestion if I am missing some point or not!
The caller of string_copy would be responsible for releasing the memory when it's done with it by calling delete[] on it.
This is, by the way, a terrible way to write C++ code. You should be using std::string or std::vector<char> or something like that.
Here's why:
int length = string_length(string_c);
char* copy = string_copy(string_c);
cout << "Copied String: " << copy << endl;
delete[] copy;
return 0;
Yuck.
In fact the ideal solution is to use std::string and not char *. 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 *.

Program crashes in the second run, after the return 0 from main C++

I have built my own functions of strlen and strdup.
When i use my strdup in the first time it's okay, i close the window, run it again, then in the end of the program after the return 0 from the main the program crashes. VS just says that it triggered a breakpoint.
#include "stdafx.h"
#include <iostream>
using namespace std;
int MyStrlen(const char* str);
char* MyStrdup(const char* str);
int main()
{
char *s1 = "Hello World!";
char *s2 = MyStrdup(s1);
cout << s1 << " , " << s2 << endl;
system("pause");
return 0;
}
int MyStrlen(const char* str)
{
register int iLength = 0;
while (str[iLength] != NULL)
{
iLength++;
}
return iLength;
}
char* MyStrdup(const char* str)
{
char* newStr;
int strLength = MyStrlen(str);
newStr = new char(strLength+1);
for (register int i = 0; i < strLength; i++)
{
newStr[i] = str[i];
}
newStr[strLength] = NULL;
return newStr;
}
Can someone note the place that makes it crash? I think it's a memory leak maybe.
Also, can you note things to improve in the code? For my learning purpose
EDIT: Thanks, I don't know why I used () instead of [] to define my new char[]. That was a memory leak or overwrite after all.
The "new" statement for an array should be with square brackets:
newStr = new char[strLength+1];
When you do
new char(c)
It allocates a single character and copies the character c into it.
When you do
new char[n]
it allocates memory for n characters
The expression new char(strLength+1) allocates a single character, and initializes it to strLength + 1. That of course means you will write out of bounds and have undefined behavior when you copy the string.
You should use new char[strLength + 1] instead, to allocate an "array" of characters.
On an unrelated note, while the terminating character in a string is commonly called the null character, it's not actually a null pointer (which is what NULL is for). Not that it really matters since in C++ NULL is a macro that expands to 0, but you should probably be explicit and use '\0' anyway (it gives more context for future readers).

wrong memory allocation new char [n]

What is wrong with this program?
#include<iostream>
using namespace std;
void main()
{
int n = 5;
char* p = new char [n];
int i;
for(i=0;i<n;i++)
{
p[i] = 'A'+i;
}
cout<<p<<endl;
}
Why do I get "ABCDExxxx" instead of "ABCDE" ?
What is wrong with memory allocation?
There's nothing wrong with the memory allocation, except that the memory is never released. Don't forget to delete [] p; before main returns.
The problem with the output is that the string that p points to does not have a terminating '\0'. In general, you should allocate an array with room for at least one more character than you're going to put into the array, and put a '\0' after the last one. Of course, a better solution is to use std::string, which takes care of all that for you.
C Strings need to be null-terminated. Add one more byte containing 0.
You can allocate the storage for char using new this way, it is OK. However if you are going to use it later with functions that relates on null terminating character (like strlen i.e, or printing this out) then when allocating the storage for a char* you need to allocate the number of characters + 1 more to store the \0. C Strings need to be null-terminated.
Why do I get "ABCDExxxx" instead of "ABCDE" ? What is wrong with
memory allocation?
your data is not null terminated (doesn't contain '\0' at the end so you are printing garbages until character '\0' is found somewhere else). To make it work as expected you can do:
int n = 5;
char* p = new char [n+1];
p[n]='\0';
for(i=0;i<n;i++)
{
p[i] = 'A'+i;
^
side note: this is OK, however if your p has been pointing to a string
literal, i.e. if it was defined as char*p = "string literal\n";
then according to section 2.14.5 paragraph 11 of the C++ standard,
it would invoke undefined behavior:
The effect of attempting to modify a string literal is undefined.
so be aware :p !
}
cout<<p<<endl;
remember then to deallocate storage with
delete [] p;
and as others commented, it might be a better idea to use std::string instead.
First of all, please don't use C style when you're already on C++
Use std::string instead
It has a member function c_str() that helps to work with C api/functions
#include<iostream>
using namespace std;
int main()
^^ main should return int
{
int n = 5;
//C string needs to be null terminated, so an extra
char* p = new char [n+1];
int i;
for(i=0;i<n;i++)
{
p[i] = 'A'+i;
}
p[i] = '\0'; //Insert the null character
cout<<p<<endl;
}
You are simply not putting a null character. Use this code:
#include<iostream>
using namespace std;
void main()
{
int n = 5;
char* p = new char [n];
int i;
for(i=0;i<n;i++)
{
p[i] = 'A'+i;
}
cout<<p<<endl;
}
As you are using c++ i recomend using std::string.
#include<iostream>
#include<string>
using namespace std;
void main()
{
//int n = 5;
//char* p = new char [n];
string s;
int i;
for(i=0;i<n;i++)
{
s.append("/*whatever string you want to append*/");
}
cout<<s<<endl;
}
when the endl met '\0' ,it return,so if you dont have a '\0' in the char[],until found it,it will continue to read memoery.

How to use char * in C

I have main function like this:
void main()
{
char *s;
inputString(s);
printf("%s",s);
}
and inputString function:
void inputString(char *&s)
{
//Some code line to input a string and set s point to this string
}
Is there have a function auto malloc memory enough store string which inputed (I need input string in inputString function).
Just 3 lines of code (put these inside int main() )are enough
std::string s;
std::cin >> s; //or getline() as desired
std::cout << s;
If you keep using this C style approach, then no, you will have to make assumptions and allocate enough memory yourself. The C++ approach is much more superior, use std::strings and don't do manual allocations:
#include <string>
#include <iostream>
void inputString(std::string& s)
{
//Don't bother for the memory management
}
int main()
{
std::string s;
inputString(s);
std::cout << s ;
}
Also do note that your code is not legal C++. void main() is illegal!!!
Edit: At the time of this answer the question was tagged C++. Later the question was retagged NOT by the OP, and I don't quite agree with it...
You're mixing C and C++ in your example.
In your case before you can use s it should be initialized. For example, like this:
void inputString(char *&s)
{
s = strdup(xxx); // or malloc, calloc, etc.
}
But really, then it's better to just use plain old C:
char* inputString(void)
{
char* s = strdup(xxx);
return s;
}
Assuming that you are doing this is C and not C++.
There are two approaches, either inputString must allocate the memory or the caller of inputString must allocate the memory.
if inputString allocates the memory your function will probably look something like:
char* inputString(void)
{
int len = strlen (MyInternalString) + 1;
char* s = malloc (len);
strncpy(s, MyInternalString, len);
return s;
} //similar to what Rustram illustrated
you should also include:
void freeString(char* str)
{
free(str);
}
as well. This makes it clear to the user that they are required to manage the memory of the returned string themselves.
Alternatively you can write inputString where the user is expected to provide the required memory. This will then look something like
int inputString(char* str, int maxLen) //
{
if (maxLen >= myInternalStringLength + 1)
{
strncpy(str, myInternalString, maxLen)
}
return myInternalStringLength + 1;
}
Here the user of my string can check the return code to see if the buffer that he allocated was big enough. If it was too small, then he can always realloc a bigger one
Your main now becomes:
int main()
{
char *s = NULL;
int len = inputString(s, 0);
s = alloca(len); //allocates the memory on the stack
len = inputstring(s, len);
printf("%s",s);
} //no need to free the memory because the memory alloca'ed gets
//freed at the end of the stack frame
int main()
{
std::string s;
inputString(s);
printf("%s",s.c_str());
}
and inputString function:
void inputString(std::string& s)
{
//Some code line to input a string and set s point to this string
std::cin >> s;
}