From: fyresoul on
I have this simple code that causes a seg. fault... help?

#include <string>
#include <iostream>

using namespace std;

int main(){

int num2, num1;
char* keyGuess;

for(num2 = 0; num2 <= 3; num2++)
{
for(num1 = 0; num1 <= 2; num1++)
{
sprintf (keyGuess,"%d%d", num1,num2);
cout<< num2<< " " << num1<< endl;
}
}
exit(0);
}

I know I could just make a string from my variables, but later I need
to use the system(char*) command, and will have to deal with this
problem sooner or later.

Thanks in advance.
From: Jack Klein on
On Thu, 31 Jan 2008 19:13:28 -0800 (PST), fyresoul(a)gmail.com wrote in
alt.comp.lang.learn.c-c++:

> I have this simple code that causes a seg. fault... help?
>
> #include <string>
> #include <iostream>
>
> using namespace std;
>
> int main(){
>
> int num2, num1;
> char* keyGuess;

keyGuess is a pointer that can hold the address of a char, which could
be the first of an array of chars. But you have not initialized it.
So you later tell sprintf() to write data to memory using an invalid
pointer.

The easiest way to correct this is to change the definition so that it
defines a large enough array of characters:

char keyGuess [100];

....should do it. The rest of the code that uses keyGuess in this
snippet does not have to change at all. In the call to sprintf(), the
name of the array keyGuess will be automatically converted to a
pointer to its first element, providing sprintf() with 100 characters
it fill with output.

> for(num2 = 0; num2 <= 3; num2++)
> {
> for(num1 = 0; num1 <= 2; num1++)
> {
> sprintf (keyGuess,"%d%d", num1,num2);
> cout<< num2<< " " << num1<< endl;
> }
> }
> exit(0);
> }
>
> I know I could just make a string from my variables, but later I need
> to use the system(char*) command, and will have to deal with this
> problem sooner or later.
>
> Thanks in advance.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
From: LR on
fyresoul(a)gmail.com wrote:
> I have this simple code that causes a seg. fault... help?
>
> #include <string>
> #include <iostream>
>
> using namespace std;

I think using namespace std; isn't a good idea. YMWV.
>
> int main(){
>
> int num2, num1;
> char* keyGuess;
>
> for(num2 = 0; num2 <= 3; num2++)

probably better to
for(int num2=0; num2 <=3; num2++)


> {
> for(num1 = 0; num1 <= 2; num1++)

similarly
for(int num1 ....

> {
> sprintf (keyGuess,"%d%d", num1,num2);

Where, that is, to what memory does keyGuess point to?

I think you'd be better off with std::ostringstream.


> cout<< num2<< " " << num1<< endl;
> }
> }
> exit(0);
> }
>
> I know I could just make a string from my variables, but later I need
> to use the system(char*) command, and will have to deal with this
> problem sooner or later.

std::ostringstream has a str() member that will yield a std::string and
std::string has a c_str() member that returns a char*.

LR



From: Francis Glassborow on
LR wrote:
> fyresoul(a)gmail.com wrote:
>> I have this simple code that causes a seg. fault... help?
>>
>> #include <string>
>> #include <iostream>
>>
>> using namespace std;
>
> I think using namespace std; isn't a good idea. YMWV.

Opinions differ when it comes to using it in a .cpp file.
>>
>> int main(){
>>
>> int num2, num1;
>> char* keyGuess;
>>
>> for(num2 = 0; num2 <= 3; num2++)
>
> probably better to
> for(int num2=0; num2 <=3; num2++)

Yes but the <= too often leads to logic errors (us humans are not very
good at handling this kind of thing.
I would consider writing the above code as:

int main(){
int const dim1(3);
int const dim2(2); // avoid magic numbers
ostringstream sink;
for(int i(0); i != dim2; ++i){
for(int j(0); j != dim1; ++j){
sink << j << ' ' << i;
cout << i << ' ' << j << '\n'
}
}
return 0;
}

<snipped>
>>
>> I know I could just make a string from my variables, but later I need
>> to use the system(char*) command, and will have to deal with this
>> problem sooner or later.
>
> std::ostringstream has a str() member that will yield a std::string and
> std::string has a c_str() member that returns a char*.

Yes. Note that it is very unusual that you need a raw array as a
sink/source for data in C++. Any time you are tempted to write one
consider whether there is a more secure alternative (especially one that
avoids the risk of a buffer overrun.
From: Daniel T. on
fyresoul(a)gmail.com wrote:

> I have this simple code that causes a seg. fault... help?

Your code could be made much simpler by using standard C++ input
functions instead of using the C input functions.

> #include <string>
> #include <iostream>
>
> using namespace std;
>
> int main(){
>
> int num2, num1;
> char* keyGuess;

Always, always, always... Initialize your variables when you define
them. What do you think keyGuess should be initialized to? The answer to
that will fix your segmentation fault problem.

In C++ prefer to not define variables until you need them.

> for(num2 = 0; num2 <= 3; num2++)
> {
> for(num1 = 0; num1 <= 2; num1++)
> {
> sprintf (keyGuess,"%d%d", num1,num2);
> cout<< num2<< " " << num1<< endl;
> }
> }
> exit(0);
> }
>
> I know I could just make a string from my variables, but later I need
> to use the system(char*) command, and will have to deal with this
> problem sooner or later.

std::string has a member function called "c_str()" that converts it to a
const char*, the 'system()' function accepts a const char*. QED.