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.
Related
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).
As in the title, I need to add user-specified number of spaces at the beginning of some word, using array of chars. I need to do it in a function which takes my array as a parameter and returns it. Here's my code:
#include <iostream>
using namespace std;
void writeDownCharArray(char t[], int sizee)
{
for (int i=0;i<sizee;i++)
{
cout<<t[i];
}
}
char * addSpaces(char t[], int ammountOfSpaces)
{
int numberOfCharacters=0;
for (int i=0; t[i]!=NULL; i++){numberOfCharacters++;} //checking the amount of characters in my array
char t2[numberOfCharacters+10];
for (int i=0; i<ammountOfSpaces; i++) {t2[i]=' ';} //adding the sapces
for (int i=ilosc;i<numberOfCharacters+ammountOfSpaces;i++) {t2[i]=t[i-ammountOfSpaces];} //filling my new array with characters from the previous one
return t2;
}
int main()
{
int numberOfSpaces;
char t[10];
cout << "Text some word: ";
cin.getline(t,10);
cout<<"How many spaces?: ";cin>>numberOfSpaces;
writeDownCharArray(addSpaces(t, numberOfSpaces), HERE);
return 0;
}
And now: How do I print it to the screen? If I say cout<<addSpaces(t, numberOfSpaces); it actually prints something strange to the screen (not numbers, just strange characters). And if I say writeDownCharArray, then what should I put in "HERE" place?
The C++ way to solve this would be to use a std::string like
std::string add_spaces(const std::string & line, std::size_t number_of_spaces)
{
std::string spaces(number_of_spaces, ' ');
return spaces + line;
}
If you cannot use std::string then you are doing to have to deal with dynamic memory allocations and change
char t2[numberOfCharacters+10];
to
char * ts = new char[numberOfCharacters + ammountOfSpaces + 1];
We have to have this as Variable length arrays are not standard and trying to return a pointer to an array declared in a function will leave you with a dangling pointer and trying to use it is undefined behavior.
Since new[] was used in the function you will need to remember to call delete[] on the pointer that is returned after you are done with it. This is another benefit of using a std::string as it takes care of itself.
As far as writeDownCharArray is concerned you do not need a size parameter as cout can handle null terminated c-strings. You can simply have
void writeDownCharArray(char t[])
{
cout<<t;
}
And then you main would look like
char * foo = addSpaces(t, numberOfSpaces);
writeDownCharArray(foo);
delete [] foo;
So I'm making a function that is similar to SubStr. This is an assignment so I cannot use the actual function to do this. So far I have created a function to take a string and then get the desired substring. My problem is returning the substring. In the function when I do Substring[b] = AString[b]; the substring is empty, but if I cout from inside the function I get the desired substring. So what is wrong with my code?
Here is a working demo: http://ideone.com/4f5IpA
#include <iostream>
using namespace std;
void subsec(char AString[], char Substring[], int start, int length);
int main() {
char someString[] = "abcdefg";
char someSubString[] = "";
subsec(someString, someSubString, 1, 3);
cout << someSubString << endl;
return 0;
}
void subsec(char AString[], char Substring[], int start, int length) {
for (int b = start; b <= length; b++) {
Substring[b] = AString[b];
}
}
Maybe this does what you're looking for? It's hard to say as your initial implementation used the length parameter as more of an end position.
#include <iostream>
using namespace std;
void subsec(char AString[], char Substring[], int start, int length)
{
const int end = start + length;
int pos = 0;
for(int b = start; b < end; ++b)
{
Substring[pos++] = AString[b];
}
Substring[pos] = 0;
}
int main()
{
char someString[50] = "abcdefghijklmnopqrstuvwxyz";
char someSubString[50];
subsec(someString, someSubString, 13, 10);
cout << someSubString << endl;
return 0;
}
There are several problems with the code:
1) The char arraysomeSubString has size 1 which cannot hold the substring.
2) The subsec is not correctly implemented, you should copy to the Substring from index 0.
Also remember to add \0 at the end of the substring.
void subsec(char AString[], char *Substring, int start, int length) {
int ii = 0;
for (int jj = start; jj <= length; jj++, ii++) {
Substring[ii] = AString[jj];
}
Substring[ii] = '\0';
}
You need to allocate more than 1 byte for someSubString i.e.
char someSubString[] = "xxxxxxxxxxxxxxxxxx";
or just
char someSubString[100];
if you know the max size you'll ever need.
Either would allocate enough space for the string you're copying to it. Then, you're not doing anything about the terminating 0 either. At the end of a C-style string there needs to be a terminating null to signify end of string. Otherwise cout will print something like;
abcdefgxxxxxxx
if you initialized with x's as I indicated.
There are a few problems with your code as it stands. Firstly, as your compiler is no doubt warning you, in C++ a string literal has type const char[], not just char[].
Secondly, you need to have enough space to store your substring. A good way to do this is for your function to allocate the space it needs, and then pass back a pointer to this memory. This is the way things are typically done in C code. The only thing is that you have to remember to delete the allocated array when you're done with it. (There are other, better ways to do this in C++, with things like smart pointers and wrapper objects, but those come later :-) ).
Thirdly, you'll have a problem if you request a length which is actually longer than the passed-in string -- you'll run off the end and start copying random memory (or just crash), which is definitely not what you want. C strings are terminated with a "nul byte" -- so you need to check whether you've come across this.
Speaking of the nul, you need to make sure that your substring ends with one.
Lastly, it's not really a problem but there's no need for the start parameter, you can just pass a pointer to the middle of the array if you want to.
char* substring(const char* str, int length)
{
// Allocate memory for substring;
char* subs = new char[length+1];
// Copy characters from given string
int i = 0;
while (i < length && str[i] != '\0') {
subs[i] = str[i];
i++;
}
// Append the nul byte
subs[i] = '\0';
return subs;
}
int main()
{
const char someString[] = "foobarbaz"; // Note -- must be const in C++
char* subs = substring(someString + 3, 3);
assert(strcmp(subs, "bar") == 0);
delete subs;
}
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';
I know a string concatenation question has been asked to death in SE. But to the best of my knowledge,I've gone through all the questions that could help me, in vain.
This is what I am hoping to accomplish with this program:
Initially I have a=0 and b=1, for n=0 and n=1 respectively.
For the next input i.e from n=3 onwards, my result should be concatenation of the previous two strings. (Like a Fibonacci sequence; only the addition is replaced by concatenation)
So,for example:
For n=3, my output should be "10".
For n=4, my output should be "101"
For n=5, my output should be "10110"
There is no logical problem with the code I've written,but I'm getting a SIGSEGV error and I don't see why.
#include <iostream>
#include<new>
#include<string.h>
using namespace std;
int main()
{
long int n,i;
char *a="0";
char *b="1";
char *c=new char[100000];
cout<<"Enter a number n:";
cin>>n;
for(i=0;i<n;i++)
{
strcat(b,a);
strcpy(a,b);
}
cout<<"\nRequired string="<<b;
}
What am I doing wrong?
strcat(b,a); invokes undefined behaviour because b points to a string literal.
char * strcat ( char * destination, const char * source );
Concatenate strings
Appends a copy of the source string to the destination string.
Since this is C++, I suggest you use std::string and the + operator. Or a std::stringstream.
The problem that you are observing has to do with undefined behavior: you are writing to the memory that has been allocated to a string literal.
To avoid the issue, you should switch to using C++ std::string: it makes your code a lot simpler by taking memory management out of the picture.
string a("0");
string b("1");
int n = 10;
for(int i=0;i<n;i++) {
string tmp(a);
a = b;
b = tmp + b;
}
cout<<"Required string="<<b;
char *a="0";
char *b="1";
"0" and "1" are string-literals (a has address of "0" and b has address of "1"), change of its contains is undefined behaviour.
strcat(b,a);
strcpy(a,b);
UB.
Since you use C++ better use std::string or std::stringstream.
You have declared a and b as
char *a="0";
char *b="1";
These are pointers to constant strings. This means that the memory allocated to these pointers is fixed. When you write past this block of memory, Bad Things(TM) will happen.
You are using strcat but your destination string is a string literal. strcat is then attempting to write past that strings terminating null character and that is where the seg fault comes in. Just don't try to modify string literals at all. Since you have the luxury of using C++ unless this is a learning exercise you would be much better off using std::string.
You can use this code instead, I am showing to you that you need to think of the inital values of n = 1, 2
also you should handle wrong inputs with n < 0
and avoid dynamic allocation as you seems to use new for no obvious reason and you forgot to free the memory with delete at the end.
#include <iostream>
#include<new>
#include<string.h>
using namespace std;
int main()
{
long int n,i;
char a[10];
char b[10];
char c[10];
//char *c=new char[100000];
cout<<"Enter a number n:";
cin>>n;
strcpy(a, "0");
strcpy(b, "1");
if (n == 1)
strcpy(b, a);
else if (n > 2)
{
for(i=2;i<n;i++)
{
strcpy(c, a);
strcat(c, b);
strcpy(a, b);
strcpy(b,c);
}
}
else if (n != 2)
cout<<"\nInvalid input!";
cout<<"\nRequired string="<<b;
}