I am trying to implement my own version of strncpy(), i found a source code from this link.
But I encountered a Unhandled exception at 0x00411ad5 in exercise 2.exe: 0xC0000005: Access violation writing location 0x00417800. everytime the code reaches this code while((x++ < n) && (*dest++ = *source++));
Here is the complete code:
char *strncpy(char * destination, const char * source, size_t n){
char *dest;
dest = destination;
size_t x=0;
while((x++ < n) && (*dest++ = *source++)); //this is where unhandled exception occurs
while(x++ < n){
*dest++ = 0;
}
return dest;
}
int main(){
char *sample = "blue";
char * sample2 = "red";
cout << strncpy(sample, sample2, 5);
getch();
return 0;
}
Please tell me why this occurs and how should I fix it? Thanks!
Your destination is "blue" which is a string literal, that is a constant. As such it is located in a read-only part of memory (and pointed at by local sample variable), thus error when writing.
Try this:
int main(){
char sample[] = "blue";
char * sample2 = "red";
cout << strncpy(sample, sample2, 5);
getch();
return 0;
}
which makes sample an array in local, writeable memory.
You cannot write to a string constant (sample); write to a char array instead:
int main(){
char *sample = "blue";
char buffer[5];
cout << strncpy(buffer, sample, sizeof(buffer));
getch();
return 0;
}
First, it was already explained to you that you can't overwrite a string that is defined like that.
Second, you cant use cout << strncpy if that function returns pointer to the end of the copied string.
There are two main problems with your program
The first one is that function strncpy has to return destination instead of dest
char *strncpy(char * destination, const char * source, size_t n){
char *dest;
dest = destination;
size_t x=0;
while((x++ < n) && (*dest++ = *source++)); //this is where unhandled exception occurs
while(x++ < n){
*dest++ = 0;
}
// return dest;
return destination;
}
The second one is that string literals are immutable. Any attempt to modify a string literal results in undefined behaviour.
Thus main function should be rewritten the following way
int main(){
char sample[] = "blue";
char * sample2 = "red";
cout << strncpy(sample, sample2, sizeof( sample ) );
getch();
return 0;
}
Also it is a bad style of programming to use variable with name x as a count. It is better to use for example i.
I would write the function simpler
char * strncpy( char *destination, const char *source, size_t n )
{
char *dest = destination;
while ( n-- && ( *dest++ = *source++ ) );
while ( n-- ) *dest++ = '\0';
return destination;
}
Related
I am still a newbie to c++; I was wondering why the code i wrote for a custom string split fuction does not work? (it splits by char and not string) I think there is something wrong with memcpy in the second instance?
char** strsplit(const char *s, const char splitboi)
{
const int LEN = length(s);
int segs = 0;
char *segstore, **out;
for (int chrs=0; chrs<=LEN; chrs++)
{
if(*(s+chrs) != splitboi)
{char* temp = chrs==0 ? (char*)"" : segstore;
segstore = new char[chrs+1];
memcpy(&segstore, &temp, sizeof(char*));
segstore[chrs] = *(s+chrs);}
else if(*(s+chrs) == splitboi)
{char **temp = out;
out = new char* [segs+1];
memcpy(&out, &temp, sizeof(char**)); //something wrong with this
out[segs] = segstore;
segs++;}
}
delete segstore;
cout << out[0] << '\n';
return out;
}
When I run the program, I get exception "heap has been corrupted" after completion of the function
I have read that this exception may cause if you are using memory that has been freed, or when you are writing to index which is out of array index. But none of the cases applies here. I have read other answers of some problems but it didn't help much.
`char fileNametoExport[26]="d:\\FOlder1\\part1.ipt";
char WorkingFolderName[260] ="d:\\folder";
int start = rFind(fileNametoExport, '\\');
int finish = rFind(fileNametoExport, '.');
if (start == -1)
start = 0;
char partname[260];
strcpy(partname,substr(fileNametoExport, start, finish));
::AfxMessageBox((LPCTSTR)partname);
char xtfile[260];
char xmltxtfile[260];
strcpy(xtfile, strcat(WorkingFolderName, partname));
strcat(xtfile, "__Default.x_t");
strcpy(xmltxtfile, WorkingFolderName);
strcat(xmltxtfile,"_XT_SE_INV_Default_SOLID_0_Solid1_xt.xmt_txt");`
function rfind() to find occurence of char in char array-
int rFind(char* s, char c)
{
int sz = 0;
char *tmp = s;
while (*tmp != '\0')
{
sz++;
tmp++;
}
for (int i = sz - 1; i >= 0; i--)
{
if (*(s + i) == c)
return i;
}
return -1;
}
function substr() to get substring from position x to y (y exclusive)
char* substr(char* s, const int b, const int f)
{
char *str = new char[f - b];
int t = 0;
for (int i = b; i != f; i++)
{
str[t] = s[i];
t++;
}
str[t] = '\0';
return str;
}
P.S- While giving input I ensure that fileNametoExport always contains '.' and '\'.
Your program do not check lengths of input strings. You can receive a string longer than your buffer and program will fail.
If your program get fileNametoExport = "d:\\somefolder\\somefilewithoutdot" , finish will be -1 and program fail at strcpy(partname,substr(fileNametoExport, start, finish)); .
Program writes after buffer in char* substr(char* s, const int b, const int f) at line
str[t] = '\0';
because t at this point equal f-b , size of str buffer.
Function _ASSERTE( _CrtCheckMemory( ) ); from <crtdbg.h> very useful when searching for bugs like this. Put it around suspicious code and it fails after your bug. It works only in debug.
I have a strange problem with c++ string object in my class on the line s.append(ptr2str ....);
class cRegexMatches {
public:
char *ptr2str;
int *pOffsets;
cRegexMatches() { ptr2str = NULL; pOffsets=NULL;}
void update(char *p, int *offsets) {
ptr2str = p; pOffsets = offsets;
printf("ptr2str=%p %s|\n", p, p);
}
string operator [] (int id) {
string s;
printf("operator[] %p %s|", ptr2str, ptr2str);
int i;
for (i=0; i<4; i++) printf(" %d", pOffsets[i]);
printf("\n");
if (!ptr2str) return s;
if (pOffsets[2 * id + 1] == 0) return s;
int len = pOffsets[2 * id + 1] - pOffsets[2 * id];
printf("size %d %ld before %s\n", s.size(), len, ptr2str + pOffsets[2 * id]);
s.append(ptr2str + pOffsets[2 * id], len);
cout << s << endl;
return s;
}
};
It runs fine with the follow code.
int main(int argc, char *argv[]) {
char *p = "10.20.0.111:8080";
int pInts[] = {0, 16, 0,16};
regmatches.update(p, &pInts[0]);
string s = regmatches[0];
int i;
for (i=0; i<s.size(); i++) {
printf("%c\n", s.c_str()[i]);
}
return 0;
}
But in my project, the line s.append(ptr2str + pOffsets[2 * id], len); seems to corrupt the first byte to be \x00, according to the debug statement printf(..) before s.append and the cout ... afterwards.
Any idea what caused the strange behavior? Thanks!
UPDATE 1
Thanks to #user657267's suggestion, here is a brief description on how the code was used in my project. It looks very innocent.
cRegexMatches globalVar;
//p points to some c string
//pInt points to an array of integers, in my case, it's 0, 16, 0, 16
globalVar.update(p, pInt);
cout << globalVar[0]
For now, I found a workaround: I changed the line s.append(ptr2str + pOffsets[2 * id], len); to return string(ptr2str + pOffsets[2 * id], len); and it worked fine. But I am still curious on what caused the strange behavior.
I believe that the problem might be your definition of the string in main.
char* p = "10.20.0.111:8080";
should be
char p[] = "10.20.0.111:8080";
Only the second definition reserves memory on the stack.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am trying to create my own char copy (like strcopy) function. It needs to be custom, I cannot use the one inside the std lib (Strcopy). I cannot change my char arrays to strings. I cannot use built in functions to copy the chars. i must use pointers to manipulate the array
I am trying to work off what the real strcopy looks like, but i cant seem toget mine to work. I THINK I want to create a pointer that points to strcpy(char destination,char source) and then I manipulate destination through source but nothing is copying over correctly and I just print out garbage. Please help open to all suggestions
void StrCpy(char *destination, char *source);
int main()
{
card card1[10], card2[10];
card1[0].cvalue = 1000;
card2[0].cvalue = 90000;
card *card1p = &card1[0];
card *card2p = &card2[0];
//set up card file to be read in
ifstream fin;
string finName;
//get file name from user
cout << "Enter file name...(cardFile.txt)" << endl;;
getline(cin,finName);
//open the file
fin.open(finName.c_str());
//check if cardFile.txt opens correctly
if(!fin.good())
{
cout << "Error with card file" << endl;
return 0;
}
else
{
card *deckPointer = NULL;
//prime fin
//fin >> deck[i].suit;
//fin >> deck[i].rank;
//fin >> deck[i].cvalue;
while(fin.good())
{
for(card1p = &card1[0]; card1p < &card1[10];card1p++)
{
fin >> (*card1p).suit;
fin >> (*card1p).rank;
fin >> (*card1p).cvalue;
}
}
}
StrCpy((*card2p).suit, (*card1p).suit);
cout << (*card2).suit << endl;
}
void StrCpy(char *destination,char *source)
{
char *p = destination;
*p = *source;
}
Usually the function is defined the following way
char * StrCpy( char *destination, const char *source )
{
char *p = destination;
while ( *p++ = *source++ );
return destination;
}
Yet another realization
char * StrCpy( char *destination, const char *source )
{
char *p = destination;
do
{
*p++ = *source;
} while ( *source++ );
return destination;
}
And one more
char * StrCpy( char *destination, const char *source )
{
for ( char *p = destination; *p = *source; ++p, ++source );
return destination;
}
or
char * StrCpy( char *destination, const char *source )
{
char *p = destination;
while ( *p = *source ) ++p, ++source;
return destination;
}
void StrCpy(char *destination,char *source)
{
char *p = destination;
*p = *source;
}
is not correct. Basically you're doing
destination[0] = source[0], which is not a actual copy.
You should read up on pointers. And formatting. And std::string.
I am doing this
char *draw_line(int n, char ch)
{
char *line = new char[50];
for(int i = 0; i <= n; i++)
line[i] = ch;
return line;
}
and while calling the function I am writing this:
char *res_line = draw_line(50, '=');
cout<<*res_line;
but instead of getting = printed 50 times in the console window, it just show = sign one time. My main aim is to return the = or any character as many times I want and output
the same to a text file. That's it.
cout<<*res_line;
is printing one char because *res_line is char, not char*.
Write:
cout<<res_line;
But wait — that is not going to work either because res_line is NOT null-terminated.
Use std::string or std::vector<char> — avoid explicit memory allocation, use RAII idiom instead:
std::string draw_line(int n, char ch)
{
return {n, ch}; //C++11
}
So simple!
Or if you use std::vector:
std::vector<char> draw_line(int n, char ch)
{
return {n, ch}; //C++11
}
which is almost same.
In C++03, however, you've to write:
return std::string(n, ch); //in the first case
return std::vector<char>(n, ch); //in the second case
That is, invoke the constructor explicitly.
The valid code will look as
char* draw_line( int n, char ch )
{
char *ch2= new char[n + 1]();
std::memset( ch2, ch, n );
return ch2;
}
//...
char *ch50 = draw_line(50,'=');
cout << ch50;
//...
delete []ch50;
Take into account this statement
char *ch2= new char[n + 1]();
But it would be much better to write simply
std::cout << std::string( 50, '=' );
char* draw_line(int n, char ch)
{
char *ch2= (char *) malloc(sizeof(char)*(n+1)); // (n+1) here
for(int i=0;i<n;i++) // < instead of <=
ch2[i]=ch;
ch2[n] = 0; // terminator
return ch2;
}
char *ch50 = draw_line(50,'=');
cout<< ch50; // changed from *ch50 to ch50
ADDON: look at string-fill constructor
cout << string(50, '=');