Why is something so seemingly simple is crashing my program?
I am trying to get a value for n to make an array the size of N and perform various operations on it, but that's beside the point. Anyways, It keeps crashing every time I try to access argv[1].
int main(int argc, char * argv[])
{
int n;
n = atoi(argv[1]); //Crashes here!
cout << "\nN: " << n << endl;
}
Does argv[1] exist? To prevent your code from accessing memory it should not check how many arguments were passed.
if(argc >= 2)
n = argv[1];
else
std::cout << "Proper usage: .....\n";
This seems like a great time to learn how to use your debugger to view the contents of argv and argc.
Related
I am writing a simple program that compares a single character from argv[] to a character in a char array. This is done using a for loop to check if argv[1] is any of the characters in the character array, which is to serve as an input error check.
What I have done to implement this is below:
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
const char validCharacters[] = "abcde01234";
int goodChars = 0;
for (int i = 0; i < sizeof(validCharacters) - 1; i++) {
if (strcmp(argv[1], &validCharacters[i]) == 0) {
cout << "Characters match!" << endl;
goodChars++;
}
}
if (goodChars > 0) {
cout << "Input OK!";
}
else {
cout << "Invalid input!";
}
return 0;
}
I inputted '0' as the value for argv[].
When I was debugging, this, I found that strcmp(argv[1], &validCharacters[i]) returns -1, and that sizeof(argv[1]) returns 4.
Why is it that argv[1] has the size of 4 despite only having '0' entered into it?
I'm certain that this is the reason why my program isn't working and would like to know if there is a way to resolve this problem.
Also, I'm not very experienced in C++, so anything you thing is bad practice, please let me know.
argv is an array of char pointers. In order to compare and get the size of the actual value, you'll have to dereference the char object.
For example, to get the size:
if(*argv[1] == '0'){
// Do Something
}
Checks if the first argument(argv[0] is the command itself), is equal to the character '0'. Here I dereference the char at index 1 of the argv array.
I'm quite new to C++(two days actually) and I would like to know if it is possible to do some parallelization with this code. I need this to be a hell lot faster as there are millions of iterations. From what I've understood so far it is not possible to parallelize, as the only for loop I use depends on the iteration before, which doesn't allow parallelization. Right? And if parallelization is not possible, how to optimize it otherwise so it gets faster. I was quite surprised as this only runs 3x faster than my original python code. (some said C++ is up to 100 to 400x faster than python)
If the VisualStudio 2015 project files are needed, please tell me..
If you run the application:
You need to enter a sha1 hash and then tell the programm how many characters the base word had, so for example the word test:
hash: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
length: 4
Thanks in advice
#include "stdafx.h"
#include <stdio.h>
#include <string>
#include <iostream>
#include <cstring>
#include "..\crytoPP\sha.h"
#include "..\crytoPP\filters.h"
#include "..\crytoPP\hex.h"
#include "..\crytoPP\channels.h"
using namespace CryptoPP;
using namespace std;
int found = 0;
int iteration = 0;
int length;
char source[] = "abcdefghijklmnopqrstuvwxyz";
string solution = " didn't match";
string base_hash;
string CHECK(string hash, int argc, char** argv);
void COMBINATIONS(string b, int length, int source_length, int argc, char** argv);
int main(int argc, char** argv)
{
char *arr_ptr = &source[0];
int source_length = strlen(arr_ptr);
cout << "Please enter hash:";
cin >> base_hash;
cout << "Please enter length:";
cin >> length;
transform(base_hash.begin(), base_hash.end(), base_hash.begin(), ::toupper);
COMBINATIONS("", ::length, source_length, argc - 1, argv + 1);
system("PAUSE");
return 0;
}
string CHECK(string hash, int argc, char** argv) {
if (::found == 0) {
iteration++;
cout << iteration << endl;
if (argc == 2 && argv[1] != NULL)
hash = string(argv[1]);
string s1;
SHA1 sha1; SHA224 sha224; SHA256 sha256; SHA512 sha512;
HashFilter f1(sha1, new HexEncoder(new StringSink(s1)));
ChannelSwitch cs;
cs.AddDefaultRoute(f1);
StringSource ss(hash, true /*pumpAll*/, new Redirector(cs));
cout << s1 << endl;
if (s1 == ::base_hash) {
::found = 1;
cout << " =" << hash << endl;
}
return s1;
}
}
void COMBINATIONS(string b, int length, int source_length, int argc, char** argv) {
if (::found == 0) {
if (length == 0) {
CHECK(b, argc, argv);
}
else {
for (int i = 0; i < source_length; i++) {
COMBINATIONS(b + ::source[i], length -1, source_length, argc -1, argv + 1 );
CHECK(b, argc - 1, argv + 1);
}
}
}
}
The first thing you should try is to remove your output in every iteration as this does significantly reduce the performance of your program.
Right now you are invoking COMBINATIONS only once with an empty string b, but if you would create one thread for every starting string b of size 1 in main you can have e.g. 26 threads each solving an equally sized part of the problem. Yet, best would be to try to rewrite the COMBINATIONS function to be better suited for parallelism.
Moreover you are currently leaking memory every time you call CHECK which right now might not seem as much as a problem, however the longer the word you are looking for, the more memory your program will require. C++ requires you to manage the memory yourself, so you should at least free all the memory you allocated with new by using delete (to make sure it can be reused). Even better if you would try to reuse those objects you created as memory allocations are somewhat slow as well.
Last but not least please rethink the purpose of incrementing/decrementing argc and argv. Frankly I do not quite understand your intention there and it seems evil.
Our instructor requires us to input data into code in the following ways:
1.Random mode
Run with graphs generated by random number generator. The command line for
this mode is:
$ mst –r n d
// run in a random connected graph with n vertices and d% of density.
// See Performance measurements section for details.
2.User Input mode
$mst -s file-name // read the input from a file ‘file-name’ for simple scheme
$mst -f file-name // read the input from a file ‘file-name’ for f-heap scheme
At present I have written the code and compiled it using g++:
g++ -o mst.o mst.cpp
I am taking input from the file like this:
./mst.o < data.txt
However, I don't know how to go about satisfying the above requirements.
An application starts in main like this:
int main(int argc, char* argv[])
These are the command line arguments.
You can print them out if you want:
int main(int argc, char* argv[])
{
std::cout << "Application: " << argv[0] << "\n";
for(int loop =1 ;loop < argc; ++loop)
{
std::cout << "\tArg: " << loop << " Value: " << argv[loop] << "\n";
}
}
You need to check the argc and argv parameters to main. If argv is large enough, check argv[1] to see if it's one of the switches you need to handle. If it is then decode the other argv for the numbers or filenames that you need. argv[0] is generally the name of the executable and isn't used.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I made a simple test program to play around with C++11 threads.
#include <iostream>
#include <stdlib.h>
#include <thread>
using namespace std;
void tee(int civ)
{
for(int loop=0; loop<19; loop++, civ++)
{
civ = civ%19;
cout << loop << "\t" << civ << endl;
this_thread::sleep_for(chrono::milliseconds(300));
}
}
void koot()
{
while(true)
{
cout << ":) ";
this_thread::sleep_for(chrono::milliseconds(300));
}
}
int main(int argc, char *argv[])
{
thread saie(tee, atoi(argv[1])),
kamaa(koot);
saie.join();
kamaa.join();
return 0;
}
It works fine as long as I supply command line arguments, but if I don't, it crashes.
How can this be solved?
I tried checking the argument count, and if they existed, to no avail.
EDIT: I had to add this line:
if(argc < 2) return 1;
It crashes because you are accessing
argv[1]
which would hold a command line argument (other than the program's name) if there was one. You should check whether argc is greater than 1. Why greater than 1? Because the first command line argument is the name of the program itself. So argc is always greater than 0. And indexing starts at 0. So if argc == 1, only argv[0] is valid.
#include <iostream>
int main(int argc, char* argv[])
{
// no need to check argc for argv[0]
std::cout << argc << " " << argv[0] << "\n";
}
argv[1] is null, causing a crash in the call to atoi(). Note that array indices in C++ are zero-based!
because you don't check if argc > 1 and you try to access argv[1]
way to solve this is first check if argc > 1 and then access argv[1].
int main(int argc, char *argv[])
{
if(argc > 1){
thread saie(tee, atoi(argv[1])),
kamaa(koot);
saie.join();
kamaa.join();
}
return 0;
}
Points to remember:
argc is by default 1. This is the argument counter that holds the no. of arguments passed to the program. By default, its 1 because the program gets the executable's name(and path)
argv holds the array of NULL terminated character arrays(or strings). argv[0] will always hold the name of the executable.
never assume user will always enter the arguments. and always do a bounds check while accessing argv or any array in the future.
Try the following code instead:
int main(int argc, char *argv[])
{
if(argc < 2) { cout<<"No command line arguments found\n Aborting!\n"; return 1;}
else { thread saie(tee, atoi(argv[1])),kamaa(koot);}
saie.join();
kamaa.join();
return 0;
}
You are trying to access a command line argument argv[1] which is not present. It is always better to check if the command line argument exists or not.
I've been stuck on this for a while and can't debug this EXC_BAD_ACCESS error. I have run NSZombie and I am pretty sure its a memory issue with argv[1] (or anything more for that matter). I've checked my syntax and libraries so I don't know why it wont store past arg[0].
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
cout << "Enter the initial bankroll" << endl;
int bankroll = atoi(argv[1]); //code faults here
cout << "Enter seed" << endl;
int seed = atoi(argv[2]);
// ...
I left out the rest because the error occurs before anything else.
The code runs in the terminal but fails the automatic grader for my class.
Arguments entered:
./blackjack 400 1
Should work for any numbers.
Shouldn't argv[0] would be blackjack, argv[1] the first number and argv[2] the second?
cout doesn't fill the elements of argv, those come from the command line used to execute your program. Also, whenever you use argv, be sure to check argc, which is the number of valid indices into argv. Your program is probably crashing because you haven't passed any arguments to your program, and so the elements of argv aren't usable.
You'll need to use cin calls to read the user input that you're expecting, or change your program to use values passed in from the command line, i.e. no prompts or reads.
Your added assumptions are correct about argv: if you execute the program with: ./blackjack 400 1, then argv[1] should be 400, and argv[2] should be 1.
Since, based on your edit, you seem to want to get these numbers from the command-line, then remove your cout calls.
As others have noted argv are command line arguments. If they are filled you just use them. I often do like this:
int
main(int n_app_args, char** app_arg)
{
std::string nec_file;
if (n_app_args > 1)
nec_file = app_arg[1];
else
{
std::cout << "Enter NEC output file: ";
std::cin >> nec_file;
}
where if I forget the command line argument the program asks me. If I remember the argument the argument is used without further intervention. You can obviously extend this to more arguments.