What's wrong here? (newbie)

C

Cursief

Hi,

I wrote this dead simple console "application" :

---
int main(int argc, char** argv)
{
char output[] = "rundll32.exe url.dll,FileProtocolHandler
someurl?file=";

if (argc == 1){
printf("You did not pass any parameters.\nAborting....");
} else {
strcat(output, argv[1]);
system(output);
}
return 0;
}
---

Couldn't be anymore simple then this. Now running this from the command
line is no problem at all, it does it's job. But when I drag a file onto
this application, windows tells me a crash has happened (the 'send error
report' window). Strange though since the code does work!!! But this
error window is annoying!

Any ideas what this could be?

thanks!
 
N

Neelesh Bodas

Cursief said:
Hi,

I wrote this dead simple console "application" :

---
int main(int argc, char** argv)
{
char output[] = "rundll32.exe url.dll,FileProtocolHandler
someurl?file=";

if (argc == 1){
printf("You did not pass any parameters.\nAborting....");
} else {
strcat(output, argv[1]);

the destination string, viz output should have enough space to
accomodate the source characters, viz argv[1]. Else behaviour is
undefined.

system(output);
}
return 0;
}
---

Couldn't be anymore simple then this. Now running this from the command
line is no problem at all, it does it's job. But when I drag a file onto
this application, windows tells me a crash has happened (the 'send error

Thats not standard C++.
 
?

=?ISO-8859-1?Q?Stefan_N=E4we?=

Cursief said:
Hi,

I wrote this dead simple console "application" :

---
int main(int argc, char** argv)
{
char output[] = "rundll32.exe url.dll,FileProtocolHandler
someurl?file=";

if (argc == 1){
printf("You did not pass any parameters.\nAborting....");
} else {
strcat(output, argv[1]);
system(output);
}
return 0;
}
---

Couldn't be anymore simple then this. Now running this from the command
line is no problem at all, it does it's job. But when I drag a file onto
this application, windows tells me a crash has happened (the 'send error
report' window). Strange though since the code does work!!! But this
error window is annoying!

Any ideas what this could be?

What's the size of 'output' ?
What does 'strcat(dst, src)' do ?


/S.
 
E

Earl Purple

Cursief said:
Hi,

I wrote this dead simple console "application" :

---
int main(int argc, char** argv)
{
char output[] = "rundll32.exe url.dll,FileProtocolHandler
someurl?file=";

if (argc == 1){
printf("You did not pass any parameters.\nAborting....");
} else {
strcat(output, argv[1]);
system(output);
}
return 0;
}
---

Couldn't be anymore simple then this. Now running this from the command
line is no problem at all, it does it's job. But when I drag a file onto
this application, windows tells me a crash has happened (the 'send error
report' window). Strange though since the code does work!!! But this
error window is annoying!

Any ideas what this could be?

You can't call strcat on your output because that concatenates
characters to the end that you have not allowed memory for. The array
output contains just as many characters as it needs to hold the initial
string, no more (well technically the compiler may fill to a 4-byte
boundary but that's not your concern).

By the way, if you want to write this in C then post at comp.lang.c
If you want to write this in C++ then you should be using std::string.

The second parameter of main should be char* argv[] not char** argv.
 
C

Cursief

Earl said:
You can't call strcat on your output because that concatenates
characters to the end that you have not allowed memory for. The array
output contains just as many characters as it needs to hold the initial
string, no more (well technically the compiler may fill to a 4-byte
boundary but that's not your concern).
You mean instead of char output[] do something like this char output[100] ?
By the way, if you want to write this in C then post at comp.lang.c
If you want to write this in C++ then you should be using std::string.

I tried the std::string functions but ->system() gave an error saying
that the passed parameter wasn't a char. That's the reason i'm using
this data type.

Any ideas on how to do the same, but not using system()??
The second parameter of main should be char* argv[] not char** argv.

thanks
 
C

Cursief

Neelesh said:
the destination string, viz output should have enough space to
accomodate the source characters, viz argv[1]. Else behaviour is
undefined.
I'm not sure what you mean! There is an else!?
Thats not standard C++.

Any direction you can point me too doing something similar??

thanks
 
?

=?iso-8859-1?q?Stephan_Br=F6nnimann?=

Cursief wrote:
[snip]
I tried the std::string functions but ->system() gave an error saying
that the passed parameter wasn't a char. That's the reason i'm using
this data type.

Use std::string::c_str()

Stephan
 
T

TB

Cursief sade:
Earl said:
You can't call strcat on your output because that concatenates
characters to the end that you have not allowed memory for. The array
output contains just as many characters as it needs to hold the initial
string, no more (well technically the compiler may fill to a 4-byte
boundary but that's not your concern).
You mean instead of char output[] do something like this char output[100] ?
By the way, if you want to write this in C then post at comp.lang.c
If you want to write this in C++ then you should be using std::string.

I tried the std::string functions but ->system() gave an error saying
that the passed parameter wasn't a char. That's the reason i'm using
this data type.

std::system( aStdString.c_str() );

TB
 
N

Neelesh Bodas

Cursief said:
Neelesh said:
the destination string, viz output should have enough space to
accomodate the source characters, viz argv[1]. Else behaviour is
undefined.
I'm not sure what you mean! There is an else!?

strcat(x,y) concatenates the c-style string y to the c-style string x.
What this means is that the string x should be large enough to
accomodate all characters from y

char x[] = "abcd";
char *y = "test";
strcat(x,y); // OOPS... array x has memory for only 4 characters. Still
you are adding more characters to it. Thats bound to crash.
Any direction you can point me too doing something similar??

Doing similar to what? If you want to write a std C++ code which
manipulates strings, you should prefer std::string.
 
E

Earl Purple

Rolf said:
Earl said:
The second parameter of main should be char* argv[] not char** argv.

They both have the exact same meaning.

They don't.

char* argv[];
char** argv2;

char * ptr;
*argv = ptr; // illegal, won't compile
*argv2 = ptr; // legal.

char ** is also non-standard, although many compilers will allow it.
(There is no law that the arguments must be called argc and argv, just
that seems to be the common tradition).
 
T

TB

Earl Purple sade:
Rolf said:
Earl said:
The second parameter of main should be char* argv[] not char** argv.
They both have the exact same meaning.

They don't.

char* argv[];

Error: Size of argv is unkown or zero.
char** argv2;

char * ptr;
*argv = ptr; // illegal, won't compile

Of course not, you have an error above.
*argv2 = ptr; // legal.

char ** is also non-standard, although many compilers will allow it.
(There is no law that the arguments must be called argc and argv, just
that seems to be the common tradition).

The following compiles.

void f1( char ** ) {}
void f2( char *[]) {}

int main() {

char a;
char * b = &a;

f1(&b);
f2(&b);

return 0;

}

The difference between 'char * a' and 'char a[7]' is that
the latter carries the type identifier 'array of 7', but
easily decays to 'char *' and loses the extra information:

void g(char *) {}
int main() {
char c[3];
g(c);
return 0;
}

TB
 
R

Rolf Magnus

Earl said:
Rolf said:
Earl said:
The second parameter of main should be char* argv[] not char** argv.

They both have the exact same meaning.

They don't.

They do.
char* argv[];

This is not a parameter. For parameters, [] means "pointer". For variable
definitions, [] is in this form invalid, because it means "array", and
arrays must have a size, which is missing in your definition.
char** argv2;

char * ptr;
*argv = ptr; // illegal, won't compile
*argv2 = ptr; // legal.

char ** is also non-standard, although many compilers will allow it.

Since for a parameter, char** and char*[] have the same meaning in standard
C++, the compiler must allow it.
 
B

BigBrian

Now running this from the command line is no problem at all, it does it's job.

It may "do it's job" but your call to strcat is stomping on what's ever
in memory next to "output". It may be that nothing important is there,
and then nothing bad happens. Or it may be that something really
important is being stored in this memory, and you're corrupting it.
Any ideas what this could be?

Writing code isn't so simple! You need to understand exactly what
you're doing or you'll end up with undefined behavior like your
example.

Your application is an example of why novice programmers should use
std::string instead of char *.

#include <iostream>
#include <string>

int main(int argc, char** argv)
{
std::string output = "rundll32.exe
url.dll,FileProtocolHandlersomeurl?file=";

if ( argc == 1 )
{
std::cout << "You did not pass any parameters."
<< std::endl;
}
else
{
output += argv[1];

system(output.c_str());
}

return 1;
}
 
E

Earl Purple

char* argv[];

Error: Size of argv is unkown or zero.

Well yes obviously in reality it will be pointing to something.
Of course not, you have an error above.

but try it in main().
The following compiles.

void f1( char ** ) {}
void f2( char *[]) {}

int main() {

char a;
char * b = &a;

f1(&b);
f2(&b);

return 0;

}

Which of these will compile? (given your prototypes above).

void f1( char ** arg )
{
f2( arg );
}

void f2( char * arg[] )
{
f1( arg );
}

(Yes obviously if you got it compiling and running it would recurse
until you got stack overflow).
 
E

Earl Purple

Earl said:
Which of these will compile? (given your prototypes above).

void f1( char ** arg )
{
f2( arg );
}

void f2( char * arg[] )
{
f1( arg );
}

(Yes obviously if you got it compiling and running it would recurse
until you got stack overflow).

Actually I was surprised on VC7 this compiled (with a warning on
infinite recursion)

Even this compiled:

void f2( char* arg[] )
{
f1( arg );
char * p;
arg = &p;
}

Didn't think arg would be an l-value.
 
C

Cursief

BigBrian said:
Writing code isn't so simple! You need to understand exactly what
you're doing or you'll end up with undefined behavior like your
example.

Your application is an example of why novice programmers should use
std::string instead of char *.

When reading all replies I realised that I was mixing C with C++ to much
and that I need to go back to the basics (which I needed anyway). Any
good reference/resource sites you can recommend? You're example did
clear things up a bit! Thanks.
 
C

Cursief

Hello everyone,

It seems that I was in bit of a hurry creating this, but all of your
comments helped alot (though I lost it at the pointers discussion a
bit). Im digging into the basics a bit more, thank god it's winter time.

Thanks again for your help....
 
D

Default User

Cursief said:
When reading all replies I realised that I was mixing C with C++ to
much and that I need to go back to the basics (which I needed
anyway). Any good reference/resource sites you can recommend? You're
example did clear things up a bit! Thanks.

A good book would server your purposes better. A strongly recommended
one is "Accelerated C++" by Koening and Moo.



Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,479
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top