I'm new to the C/C++ game so I assume I'm making a rookie mistake:
int main(){
char* clen;
clen = getenv("CONTENT_LENGTH");
if (clen==NULL){
cout << "No such ENV var: CONTENT_LENGTH"<<endl;
exit(0);
}
int cl = 0;
cl = atoi(clen);
if (cl < 1){
return inputPage();
}
// if there is no content, we assume that this is a fresh request,
// so we showed the input page, otherwise, we'll return dispatch to
//the processing code.
postTest(clen);
}
This is supposed to be a CGI script. As far as I can tell with GDB, print statements, etc. this code segfaults on the line "cl = atoi(clen);" I have no idea why this is. K&R suggests that this is correct. I basically copied this line from a half dozen other online tutorials. And it seemed to be working last night! I'm totally stumped.
I don't believe that it really crashes on atoi()
Could you please try out this code?
#include <iostream>
#include <stdlib.h>
#ifndef NULL
#define NULL 0
#endif
using namespace std;
int main(){
char* clen;
clen = getenv("CONTENT_LENGTH");
if (clen==NULL){
cout << "No such ENV var: CONTENT_LENGTH"<<endl;
exit(0);
}
int cl = 0;
cl = atoi(clen);
if (cl < 1){
std::cout << "return inputPage();" << std::endl;
return 0;
}
std::cout << "postTest();" << std::endl;
}
compile it e.g. to "app" and run it with some variations of CONTENT_LENGTH, e.g.
./app
CONTENT_LENGTH=4 ./app
CONTENT_LENGTH=-4 ./app
CONTENT_LENGTH=a ./app
Barring compiler bugs and a bugged getenv() implementation I would say that it's impossible for that code to segfault on cl = atoi(clen). This is because getenv() returns either NULL or a valid pointer to a null terminated character array (that's just a fancy way to say C string).
Since the NULL case is checked against, most likely the program (it's not a "script") crashes somewhere else.
EDIT: How do you know it even crashes? Does it display an HTTP 500 error? If yes most likely you simply forgot cout << "Content-type: text/html\n\n". What do the web server logs say?
EDIT2: unrelated to your problem, but usually using C functions like atoi() is frowned upon; the C++ version lexical_cast (implemented in TR1 and boost) is preferred.
You write you've been looking at it with GDB. Shouldn't it be possible to just dig (step) into the atoi() function call to get a better idea of what's going on? I assume you made sure it never reaches the line past the atoi() call?
It turns out that this was not in any way an issue with atoi, or with C++ in general. The problem was that I had forgotten a very basic CGI point, which is that there is no CONTENT_LENGTH in a GET, which is what the first call from the browser inevitably is. Thus, I was trying to fiddle with the clen which was null. I simply needed to return the inputPage as soon as I discovered that there was no CONTENT_LENGTH attribute.
Related
I'm new to the site and browsed several similar sounding questions but haven't found my exact problem. I suspect I'm making elementary mistakes. A link to an answer would be appreciated, or an explanation, and again I'm sorry if my question doesn't even match the title of the post.
For c++ on the Cxxdroid app for android and in Visual Studio C++:
I'm trying to experiment with classes and namespaces to provide flexible utility to the class. I want to use different implementations of the same function for personal analysis of certain algorithms on data structures; namely arrays vs lists/trees and also between recursive and iterative implementations of standard procedures. I know how to do asymptotic analysis but my stubborn mind wants real numbers.
Unfortunately, however, I can't even seem to get namespace functions to work without blowing up normal functionality. Please note, I haven't learned c++ formally yet because I'm exploring ahead of my introductory c/c++ course.
For example:
#include <iostream>
namespace iterative{
int power(int base,int expo){...}
}
namespace recursive{
int power(int base,int expo){...}
}
int main(int argc,char* argv[]){
int result = 0;
int num = 3;
int exp = 2;
//Expecting 9 in result
std::cout << "This prints fine" << std::endl;
result = iterative::power(num,exp);
std::cout << result;
std::cout << " This number and text doesn't print" << std::endl;
return 1;
}
I had a much more complex function with classes above the namespaced functions (search function for node classes inside a list/tree class) but it never worked. Then I just threw together the above snippet and tried to print result but the std::cout never fired after my function call.
Can anyone offer insight into what I'm doing wrong here? The first cout prints and the second wont. Further, execution hangs during the function call; the solution keeps running until I force it to stop.
I've tried to comment out one of the namespaces while using the other.
I've tried the using keyword with the namespace_name.
I've tried passing integers without variable usage: result = power(3,2);
I've tried printing the function result directly: std::cout << power(3,2) << std::endl;
I can't seem to get it to work on either application. I know this seems like a silly and simple question but after about a week of browsing the internet I'm inundated with very vague answers to questions regarding syntax. Perhaps I'm just not connecting the dots to my own problem...
Is my syntax in definition wrong?
Is my syntax in calling the function wrong?
Is my syntax in variable assignment wrong?
I'm at my wits' end.
Edit:
Now I feel really stupid.
You were correct. I didn't increment my variable in the iterative implementation, which meant it hung up on an infinite loop. I had to print the loop to see the numbers spitting out like I'm Neo in The Matrix. Unfortunately, I didn't test the recursive function because it felt dangerous to do so if I couldn't even get the iterative function to call first...
I was so focused on using namespaces for the first time that I never looked at the loop properly.
Thank you, and sorry for the bother. I'm going to try to extend this experiment to namespace-defining class member functions now.
Edit2: Feel free to delete this...unless it's felt that my stupidity can help others.
Silly mistake was made:
...
int power(int base,int expo){
int i = 0;
int retval = 1;
while( i < expo ){
retval *= base;
//Never did i++; or i = i + 1;
//Had to std::cout << retval; in loop to catch it
}
return retval;
}
...
I was working on an assignment for class, and I think I got the program working properly, but now I would like to make some modifications to it just to better understand assert. The code is below -
#include <iostream>
#include <stdlib.h>
#include <assert.h>
using namespace std;
// Sample program that shows how command line arg works, in Unix g++
// Note argc and argv
// Also shows use of system call, that can launch any program
// system launches 'ls' to display files in the dir
void runAssert(int);
int main(int argc, char *argv[])
{
cout << "Number of inputs: " << argc << endl;
cout << "1st argument: " << argv[0] << endl;
system ("ls");
cout << "hello world" << endl;
runAssert(argc);
return 0;
}
void runAssert(int argc)
{
assert(argc > 4);
}
So the program is supposed to keep track of the arguments passed into main through command line. The professor specified that it should take 4 arguments. This code works, as far as I can tell, but I don't know what 4 commands to pass it? I do g++ assignment.cpp -o assignment
and then ./assignment -- But this last command only counts as one argument so the assert triggers. If I change the function to >= 1 then it works.
Another question I have is, how can I make it display an error message when it doesn't meet the requirements?
I have tried assert("Not the right amount of arguments", argc > 4) but then I get an error message about too many arguments being passed into main.
Thanks for any help, and sorry if my formatting is wrong. First time posting.
This is a completely incorrect usage of assert. Use assert to state things that you, as a programmer, think are logically necessary. It is logically possible for someone to call your program with fewer than 4 arguments, so assert is not correct.
A common usage of assert is at the start of a function. (This is not validating arguments.) Consider int foo(void *k){ assert(k != NULL); ...} Once again, this is not validating the argument k. The assertion is a piece of documentation that tells the human writing the code at the call site that foo is not to be called with a NULL argument. It is a claim that in the properly written code, it is a logical necessity that k be non-null. If you want to validate the argument and generate a pretty error message, use an if statement.
One thing about assert is that you should assume it does not execute in normal operation. Typically, the program will be compiled with -DNDEBUG, which will turn all of the assertions into whitespace.
ok the number of arguments should be checked before you start executing any of the program code.
In this case i guess the professor wanted you to pass the arguments passed to the program to ls .so it should be something like
./assignment -l -s -a
In the above case the -l -s and -a are the arguments.
You can use an if condition to check the number of arguments instead of assert.
if (argc < 4) {
// print the error message
// exit from program
}
Check answer by william to know the reason why not to use assert in this case
I don't know what 4 commands to pass
That's up to you. You could do:
./assignment a b c d
You will get get argv[1]="a", argv[2]="b", etc.
Parsing and using these arguments is up to you; in this context you could try to find an example of processing the arguments. Maybe print them in reverse order or something basic like that ?
Regarding assert(): your usage is not strictly correct as pointed out in another answer.
To answer your question, one simple way to display a message is by using && : https://stackoverflow.com/a/3692961/2750093
I don't think your professor would like that though, so you could do something a little bit more naive :
if (argc <= 4 )
{
printf("Not the right amount of arguments\n");
assert(false); // or return -1;
}
assert(condition) crashes the program with an error message like file bar.cc line 123: assertion failure 'condition'. As such it is not useful for the user, but it is useful for the developer.
Use assert to express expectations (on the state of certain internally controlled variables) that are assumed to hold in the code immediately following the assertion. Don't use assert to check user input (externally controlled variables), but throw an exception instead. Exceptions can be caught by the user, assertions cannot.
I was playing around with vectors of vectors in C++. In my case what I call a 3D-vector is shown in the following code
typedef std::vector<double> RandomSample;
typedef std::vector<RandomSample> TimeSample;
typedef std::vector<TimeSample> Option;
int main(int argc, const char * argv[])
{
unsigned int numberOfOptions = 3;
unsigned int timeNodes = 7;
unsigned int numberOfRandSamples = 10;
Option options(3, TimeSample(7, RandomSample(numberOfRandSamples)));
std::cout << options[0][0][0] << std::endl;
//std::cout << options[3][6][9] << std::endl; //SEGMENTATION FAULT
//std::cout << options[2][7][9] << std::endl; //SEGMENTATION FAULT
std::cout << options[2][6][20] << std::endl; //NO ERROR !!
std::cout << "Hola Mundo !" << std::endl;
return 0;
}
The code says by itself the problem, when accessing beyond the vector bounds for the first and second indices I get the expected runtime error, but when doing the same with the third index it doesn't happen, no error, no nothing at all. I've even tried with big numbers in the third index and still everything, apparently, is working fine. What am I missing or what is going on with this code?
I'm developing on Mac OS X 10.8.4 + Xcode 4.6.3
If you're expecting a runtime error when accessing a vector outside bounds with operator[] then it's your expectation that is wrong.
When you make that kind of mistake the C++ standard says that it's "undefined behaviour", not "runtime error".
In C++, for performance reasons, there are very few runtime error angels (i.e. checks that you're not doing something wrong at runtime) so unless you specifically request them (e.g. using std::vector::at() instead of std::vector::operator[]) or unless you implement them yourself no check will be done and whatever happens happens.
Sometimes when doing this kind of mistake you get an immediate crash, but that happens only when you're very lucky. In most common cases instead you end up corrupting data that belongs to some other object or to the runtime library and one million instructions executed later a perfectly innocent part of the program starts behaving like crazy.
Murphy says that you will only get a crash if you're giving a demonstration of your software in front of potential investors and your family. Until that point everything will seem to work perfectly even if you overwrite memory that wasn't yours.
The main philosophy of C++ is that programmers never make this kind of error ;-)
I have a bunch of code roughly equivalent to this:
bool test(double e, short a, short b, short c) {
// Things being calculated here...
cout << "debug_3" << endl;
return (1 - abs(cos_th)) < (1 - cos(e));
}
int main() {
// something...
cout << "debug_0" << endl;
if(test(e,1,2,0)) {
cout << "debug_4" << endl;
// Bunch of useful operations...
}
// something...
}
Running the code generates the output:
debug_3
After which the program crashes (displaying "The program has stopped working..." in Windows). I have never encountered crashing at value return and I don't know what causes it or how I could fix it. Any thoughts on the issue?
EDIT: Some more info:
In my builds I also verify that the values of cos_th and e are valid.
People seem to point to the second something as the source of problems but my problem seems resolved (i.e. no crashes) when I get rid of the if-statement with a call to test()...
The only things we can fix without knowing what system is, is to change the type of a b and c to unsigned short since they are just array indexes, and make sure they are within array bounds. You might also need to make sure this is not zero since you divide by the result:
sqrt((Xca*Xca+Yca*Yca+Zca*Zca)*(Xba*Xba+Yba*Yba+Zba*Zba))
Use cerr instead of cout to make sure the output is flushed but you still don't see debug 4.
Put more output inside an else condition or after the if: maybe the function returns false?
If you can't locate the error precisely, use a debugger.
Crash at return usually means that your function overwrites stack (and thus the return address) and your program jumps to nowhere. You can verify this by stepping instruction by instruction at the disassembly level.
This code is C/C++ and runs without warnings or debug messages. I'm using Code::blocks with the GNU GCC compiler. This app worked perfectly once, then somewhere along the lines I messed up without noticing. Now every time it will allow a ip address input, but then freeze up and close. Why?
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
int ip[3];
char * inputIP;
int x;
string classValue;
void subnetClass()
{
if (x==0) classValue="Error: first octet may not be zero.";
if (x>0 && x<=126) classValue="Class A";
if (x==127) classValue="Loopback Address";
if (x>=128 && x<=191) classValue="Class B";
if (x>=192 && x<=223) classValue="Class C";
if (x>=224 && x<=239) classValue="Class D";
if (x>=240 && x<=255) classValue="Class E";
if (x>255) classValue="Error: an octet may not be more than 255.";
cout << classValue << endl;
}
int main()
{
cout << "Enter IP address in dotted-decimal form." << endl;
cin >> inputIP;
scanf(inputIP, "%d.%d.%d.%d" , &ip[0],&ip[1],&ip[2],&ip[3]);
int x=ip[0];
subnetClass();
return 0;
}
Build Log:
Checking for existence: C:...\IP subnetting app\bin\Debug\IP subnetting app.exe
Executing: "C:...\CodeBlocks/cb_console_runner.exe" "C:...\IP subnetting app\bin\Debug\IP subnetting app.exe" (in C:...\IP subnetting app.)
Process terminated with status -1073741510 (0 minutes, 27 seconds)
You are declaring a variable 'x' that is hiding the global one.
int x=ip[0];
However, don't do it this way. Add an int parameter to subnetClass and pass in the value that way, and remove the global variable.
Really, removing all of your globals should be a goal and easy to accomplish. Several are only used in main().
It might have worked with a little help from sheer luck even if you messed things up later, I believe. More or less everything is wrong. First you read the line into the area pointed to by uninitialized pointer (or maybe you read the pointer value, I'm not even sure what >> (char*) is supposed to do). You better change the definition to
std::string inputIP;
then you try to parse it used scanf and pass this pointer as a format string. What you meant is using sscanf. Assuming you changed the inputIP type, you can use
sscanf(inputIP.c_str(),"%d....
Then you assign to local main variable x that shadows global, which remains uninitialized when you use it in the function. Just remove the int part in the assignment like this:
x=ip[0];
and make the ip array of four elements.
int ip[4];
Then it may work. Unless I missed something else.
And one more thing: if you use some source control (for instance using git you may start new project in no time) then you'd know what you've changed when you mess up, just commit early, commit often.
Use sscanf instead of scanf