I am trying to converts a sequence of multibyte characters to a corresponding sequence of wide characters using the mbstowcs_s function. But I keep having the following heap corruption problem. Can anyone tell me how to fix that?
Here is a sample code. When debugging, it is always the line delete wc_name causing the problem. I know it shouldn't be it.
#include <Windows.h>
#include <iostream>
#include <string>
int main (int argc, char *argv[]) {
size_t returnValue; // The number of characters converted.
const size_t sizeInWords = 50; // The size of the wcstr buffer in words
const char* c_name = "nanana"; // The address of a sequence of characters
wchar_t *wc_name = new wchar_t(50);
errno_t err = mbstowcs_s(&returnValue, wc_name, sizeInWords,
c_name, strlen(c_name) );
wcout << wc_name << endl;
delete wc_name;
return 0;
}
wchar_t *wc_name = new wchar_t(50); should be wchar_t *wc_name = new wchar_t[50]; to allocate an array. And corresponding delete wc_name should be delete[] wc_name;. BTW, if you know the size of the array at compile time itself, there is no need for dynamic memory allocation. You can simply do wchar_t wc_name[50];.
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).
If it makes sense.
This is how it looks so far.
#include <iostream>
int main()
{
char *buffer;
buffer = new char[100];
std::cin >> buffer;
const int size = strlen(buffer);
char input[size];
delete buffer;
return 0;
}
I know I can use the string library but I'm trying to do without it.
I want to make the char size (in the code char input) depending on the input size.
The errors which I am getting is
expression did not evaluate to a constant
expression must have a constant value
on line 12 which is the
char input[size];
I know I can use the string library but I'm trying to do without it.
You can use std::vector<char>. If that is not an option either, allocate memory yourself and make sure that you deallocate the memory.
char* input = new char[size+1]; // Add an extra for the terminating null characterr
....
delete [] input;
For std::cin you need to pre-allocate a buffer. If you plan on using char[] and you really have to avoid strings you have to make sure you allocate enough memory.
Alternatively you can read char by char with scanf("%c",&newChar) until user inputs an escape character and allocate memory for array as you go.
I don't suppose you're limited to using iostream ?
If it is the length of used space in the buffer array you are trying to assign to size for the input array, there are two methods you can use...
#include <iostream>
using namespace std;
int main()
{
char *buffer = new char[100];
cin >> buffer;
int spaceUsed = 0;
for (unsigned int i = 0; i < 100; i++)
{
if (buffer[i] != '\0')
spaceUsed++;
}
char input[spaceUsed];
delete [] buffer;
return 0;
}
OR...
#include <iostream>
using namespace std;
int main()
{
char *buffer = new char[100];
cin >> buffer;
int spaceUsed = 0;
while (*buffer++)
spaceUsed++;
char input[spaceUsed];
delete [] buffer;
return 0;
}
Both code snippets do the exact same thing. Of course, using the string library would make your life much easier though.
I've a simple question about string/char. I've tried to implement a basic system like this;
#include <stdio.h>
#include <string.h>
int main()
{
//I'll use 'char*' for socket receive buffer!
const char* input = "This is a test!";
char n[4];
strncpy(n, input, 4);
printf("%s\n%i\n", n, strlen(n));
return 0;
}
And I got this output:
Thisd0#
7
What's wrong? This is a simple as a for/while loop (IDK).
You still need to put a null-terminating char (\0) at the end.
char n[5] = { '\0' }; // Initializes the array to all \0
strncpy(n, input, 4);
Your n char needs to be 5 bytes big (4 characters + null-terminater). You're seeing gonk afterwards because there is no null-terminator \0.
Below is my sample code. Its just a sample which is similar to the code which i'm using in my applicaiton.
#define STR_SIZE 32
void someThirdPartyFunc(const char* someStr);
void getString(int Num, const char* myStr)
{
char tempStr[] = "MyTempString=";
int size = strlen(tempStr) + 2;
snprintf((char*)myStr, size, "%s%d", tempStr, Num);
}
int main()
{
const char * myStr = new char(STR_SIZE);
getString(1, myStr); // get the formated string by sending the number
someThirdPartyFunc(myStr); // send the string to the thirdpartyFunction
delete myStr;
return 0;
}
I am getting an exception if i use this code. I think the problem is with deleting the "myStr". But delete is really necessary.
Is there any other way to format the string in getString and send it to the ThirdPartyFunc??
Thanks in advance.
you are allocating not an array of chars but one char with this line:
const char * myStr = new char(STR_SIZE);
and that one allocated char is initialized with the value of STR_SIZE, causing a "char overflow" in this case.
if you want an array of size STR_SIZE:
const char * myStr = new char[STR_SIZE];
(note the rectangular [ ]). you have to deallocate such allocated chunk of memory by using the delete[] operator.
personal note: the code you have written above (manually allocated strings etc) is good educational wise; you will do a lot of such mistakes and thus learn about the inner workings of C / C++. for production code you do not want that, for production code you want std::string or other string-containers to avoid repeating string-related mistakes. in general you are not the one who sucessfully reinvent how string-libraries will work. the same is true for other container-types like dynamically-growable-arrays (std::vector) or dictionary-types or whatever. but for educational fiddling around your code above serves a good purpose.
there are other problems in your code snippet (handing over const char* to a function and then modifying the ram, not calculating correctly the size parameter when calling snprintf etc), but these are not related to your segfault-problem.
Re the technical, instead of
const char * myStr = new char(STR_SIZE);
do
char const myStr[STR_SIZE] = "";
Note that both have the problem that the string can’t be modified.
But you only asked about the allocation/deallocation problem.
But then, there's so much wrong at levels above the language-technical.
Here's the original code, complete:
void someThirdPartyFunc(const char* someStr);
void getString(int Num, const char* myStr)
{
char tempStr[] = "MyTempString=";
int size = strlen(tempStr) + 2;
snprintf((char*)myStr, size, "%s%d", tempStr, Num);
}
int main()
{
const char * myStr = new char(STR_SIZE);
getString(1, myStr); // get the formated string by sending the number
someThirdPartyFunc(myStr); // send the string to the thirdpartyFunction
delete myStr;
return 0;
}
Here's how to do that at the C++ level:
#include <string> // std::string
#include <sstream> // std::ostringstream
using namespace std;
void someThirdPartyFunc( char const* ) {}
string getString( int const num )
{
ostringstream stream;
stream << "MyTempString=" << num;
return stream.str();
}
int main()
{
someThirdPartyFunc( getString( 1 ).c_str() );
}
The #define disappeared out of the more natural code, but note that it can very easily lead to undesired text substitutions, even with all uppercase macro names. And shouting all uppercase is an eyesore anyway (which is why it's the macro name convention, as opposed to some other convention). In C++ simply use const instead.
I am writing a very simple program that removes duplicate chars from a string. I ran it visual studio and got the error:
Unhandled exception at 0x00d110d9 in inteviews.exe: 0xC0000005: Access violation writing location 0x00d27830.
I really don't see what the problem is. current cell gets the value of the next cell.
void remove(char *str, char a) {
while (*str != '\0') {
if (*(str+1) == a) {
remove(str + 1, a);
}
*str = *(str +1 );//HERE I GET THE ERROR
++str;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char *str = "abcad";
while (*str != '\0') {
remove(str,*str);
str++;
}
std::cout << str << std::endl;
return 0;
}
EDIT:
I already tried to change it to char str[] = "abcad" but I still get the same error.
You're attempting to modify a string literal. You can't do that.
char *str = "abcad";
That's a string literal. It's created in read-only memory therefore attempting to write to it is an access violation.
One problem is that you created a read-only string literal and attempted to modify it:
char *str = "abcad"; // String literals are read-only!
You could use a char array instead:
char str[] = "abcad";
There are all sorts of problems with your program. I begun by trying to write them all down but I feel that code is irredeemable. It has indexing errors, parameter passing errors, dubious recursion and so on.
The other answers that point out the error of trying to modify a read-only literal are correct. That is the cause of the error in the code you posted.
The main reason for your troubles, in my view, is that the code is harder to write when you only have a single buffer. You have tied yourself in knots trying to get around this limitation in your design, but with a second buffer to work with, the code is trivial.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
const char *input = "abcad";
char *output = malloc(strlen(input)+1);
char *in = input;
char *out = output;
while (*in)
{
if (*in != input[0])
{
*out = *in;
out++;
}
in++;
}
*out = '\0';
printf("%s\n", output);
free(output);
return 0;
}
If you want to get really clever you can in fact manage happily with just a single buffer, so long as you keep two distinct pointers for iteration.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char str[] = "abcad";
char compare = str[0];
char *in = str;
char *out = str;
while (*in)
{
if (*in != compare)
{
*out = *in;
out++;
}
in++;
}
*out = '\0';
printf("%s\n", str);
return 0;
}
Note that we had to take a copy of first character in the buffer, the character being removed, since that may be modified by the iteration.
So now you are back where you started, with a single buffer. But now the code works and is easy to understand.
Note that my answer is written in C as per your tag, but note that your code is C++.
Since string literal is created in read-only memory, attempting to write to it is an access violation. What you can do is strcpy(dst, src) to a character array.
#include <stdlib.h>
int _tmain(int argc, _TCHAR* argv[])
{
char *str = "abcad";
char str2[10];
strcpy(str2, str);
while (*str2 != '\0') {
remove(str2, *str2);
str2++;
}
}