ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Could anyone explain what is wrong with the code below? The thing is that it fails to print any of the statements that follow the while loop but it does not generate any warnings or messages and the program appears to exit fine. The problem does not manifest itself when I replace the part in bold with the alternative code.
Now, obviously, since I am tokenizing a string that does not contain any instances of the specified delimiter, there will be only one token. So if I run the original code, the while loop as it stands will try to print an empty pointer. I can see how this is no good but I am surprised that it does not result in a segmentation fault or any other indication of a logic error. From the output of the program, one would not be able to tell that something is wrong.
cout << "Comparison of string1 and string2: " << strcmp(ar1, ar2) << endl;
char * appended = strncat(ar2, ar1, 5);
appended[arraysize+5] = '\0';
cout << appended <<endl;
char * cPtr=appended;
int count=0;
for (; *cPtr!='\0'; cPtr++)
count++;
cout << "Size of appended: " << count <<endl;
cout << "Tokenized: " << endl;
char *tok = 0; tok = strtok(appended, " ");
cout << tok << endl;
while (tok!=NULL){
tok = strtok(NULL, " ");
cout << "before printing" << endl; // this line printsbut all that follows disappears
cout << tok << endl; //does not point to anything
cout << "after printing" << endl;
}
int x = NULL;
cout << x << endl;
alternative code:
Quote:
tok = strtok(appended, " ");
while (tok!=NULL){
cout << tok << endl;
tok = strtok(NULL, " ");
You should get a seg fault at the following location as you are indexing out of bounds
Are you sure? As I understand it, strncat appends n units from the second argument to the string specified by the first argument, overwriting its terminating null, and then it returns the first argument. I assign that result to a new pointer to a char so there aren't any bounds - obviously, a pointer isn't quite the same as an array; so the only thing that delimits the string is its terminating null - which is missing since I appended only the first five characters of ar1, dropping its terminating null. That is why I add a '\0' in the next statement. No problem as far I can see. It is really the tokenizing that does not run as expected. Here is the whole thing, by the way:
Code:
# include <iostream>
using std::cout;
using std::endl;
# include <cstring>
using std::string;
using std::strcpy;
int main(){
const char * ar1 = "hello";
const int arraysize = 5;
char ar2[arraysize+1];
strcpy(ar2, ar1);
cout <<"Size of array 2: " << sizeof ar2 << endl;
cout << ar2 << endl;
cout << "Comparison of string1 and string2: " << strcmp(ar1, ar2) << endl;
char * appended = strncat(ar2, ar1, 5);
appended[arraysize+5] = '\0';
cout << appended <<endl;
char * cPtr=appended;
int count=0;
for (; *cPtr!='\0'; cPtr++)
count++;
cout << "Size of appended: " << count <<endl;
cout << "Tokenizing: " << endl;
char *tok = 0;
tok = strtok(appended, " ");
cout << tok << endl;
while (tok!=NULL){
tok = strtok(NULL, " ");
cout << "before printing" << endl;
cout << tok << endl;
cout << "after printing" << endl;
}
int x = NULL;
cout << x << endl;
return 0;
}
Are you sure? As I understand it, strncat appends n units from the second argument to the string specified by the first argument, overwriting its terminating null, and then it returns the first argument. I assign that result to a new pointer to a char so there aren't any bounds - obviously, a pointer isn't quite the same as an array; so the only thing that delimits the string is its terminating null - which is missing since I appended only the first five characters of ar1, dropping its terminating null. That is why I add a '\0' in the next statement.
Yes I am quite sure lets take a look at the source
Code:
const char * ar1 = "hello";
const int arraysize = 5;
char ar2[arraysize+1];
strcpy(ar2, ar1);
cout <<"Size of array 2: " << sizeof ar2 << endl;
cout << ar2 << endl;
cout << "Comparison of string1 and string2: " << strcmp(ar1, ar2) << endl;
/*the next line is why I feel you are confused with strncat the pointer returned is ar2 and it does not allocate more memory,
quote from page I linked to "Pointer to the destination array, which should contain a C string, and be large enough to contain
the concatenated resulting string, including the additional
null-character." ok you copy the pointer arg2 to appended*/
char * appended = strncat(ar2, ar1, 5);
/*now here appended is an alias for ar2 which has a size of 6 (arraysize+1)
yet you try and index "10" this is out of bounds of the stack memory and it should be blowing some whistles here,
"toot toot, abandon ship" lol*/
appended[arraysize+5] = '\0';
Hmm, I'm learning from a book that has most of the string operations in its very last chapter so it will be a few more weeks before I get round to that.
Thanks for your suggestions. I'll try them out when I get home.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.