When I compile and run this program via gcc(g++)/Cygwin it compiles and acts as expected.
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
for (int arg = 1; arg <= argc; arg++)
{
cout << argv[arg] << endl;
}
return 0;
}
However, when compiling with Visual Studio 13, the program compiles but I am given an access violation upon execution. What gives?
Unhandled exception at 0x000B5781 in demo.exe: 0xC0000005: Access violation reading location 0x00000000.
argv is a pointer to the first element of an array containing argc+1 elements. The first argc elements of this array contain pointers to first elements of null terminated strings representing the arguments given to the program by the environment (commonly the first of these strings is the name of the program, followed by the command line arguments).
The last element of this array (the argc+1th element, which argv[argc] refers to) is a null pointer. Your code dereferences this null pointer, leading to undefined behaviour.
The important thing to note here is that array indexing in C++ is zero based, rather than one based. This means that the first element of an array arr of length n is arr[0], and the last element is arr[n-1]. Your code appears to assume that the first element of such an array is arr[1] and that the last element is arr[n].
Related
I want to make an array, and inside this array there are pointers, like this:
int *arrp[size]; and I want the user to enter the size of it.
I tried to do this:
#include <iostream>
using namespace std;
int main ()
{
int size;
cout << "Enter the size of the array of pointers" << endl;
cin >> size;
int *arrp[size];
return 0;
}
but this doesn't work.
I also tried to do this:
#include <iostream>
using namespace std;
int main ()
{
int size;
cout << "Enter the size of the array of pointers" << endl;
cin >> size;
int* arrp[] = new int[size];
return 0;
}
also doesn't work, can someone help?
The error of the first code is that the size must be constant, I tried to fix that by writing the 2nd code but it gives an error for the word "new" in line 9:
E0520 initialization with '{...}' expected for aggregate object
and another error for the size in the same line:
C2440 'initializing': cannot convert from 'int *' to 'int *[]'
To make an array of pointers you should type: int** arr = new int*[size]
we type 2 stars '*', the first mean a pointer to an integer, the second means a pointer to the pointer to the integer, and then we make a place in the memory for those pointers by typing = new int*[size], you can use this as a 2D array that stored in the heap (not the stack) go to this website to know the difference: https://www.geeksforgeeks.org/stack-vs-heap-memory-allocation/.
to know more about how to use an array of pointers to a pointer to an integers you can see this video: https://www.youtube.com/watch?v=gNgUMA_Ur0U&ab_channel=TheCherno.
I want to use parameters in a program I made in C/C++ languages. Example:
MaxPayne2.exe -developer -developerkeys
I want to use a parameter like this in my exe file. How can I do it?
https://en.cppreference.com/w/cpp/language/main_function
While I would usually recommend adding more context this is your answer.
The standard c++ main has two additional parameters,
int main (int argc, char *argv[]) { }
To use these "arguments" (as they are called) you just reference their point in the argv array.
argc = the number of additional arguments supplied.
argv = the array of argument values supplied.
Example:
int main (int argc, char *argv[])
{
cout << argv[argc-1]; //Prints out the last argument supplied.
}
(note)If my syntax is wrong someone please correct me, my c++ is a bit rusty.
What I'm trying to do is get the user to input a phone number in a format they prefer and then remove the helper characters the user has used in their input using a loop which compares each character in the string with a another set of defined helper characters, if there is a match it erases that character from the string. I'm doing this as a practice problem to develop my understaing of iterators. I have successfully done this with the trivial for loop. However when I try to do it this way to my surprise whenever there are two helper characters like the "(+" the loop does not run for the next character which in this case is the "+". It direclt skips to the "9" and works fine after that. It does the same behaviour if other helper characters are present later on in the string. I have checked this by placing a cout << *i just under the first for loop. I don't understand why this would happen? Because of this the program fails to do what it's supposed to and out puts "+91892333" instead of the desired "91892333".
#include <iostream>
#include <string>
using namespace std;
int main()
{
string main = "(+91)892-333";
string dictionary = "(+)-";
for( string::iterator i = main.begin(); i != main.end(); i++)
{
for( char word : dictionary)
{
if(*i == word)
{
main.erase(i);
break;
}
}
}
cout << main;
}
According to the documentation erase invalidates iterators. So after you call erase you must not use iterators obtained before or you get UB. In your case erase does not change iterator but moves the end if the string after erased symbol one symbol left. So your iterator now points to the next character. But that behaviour is not guaranteed, std::string may allocate new buffer and move the data there, leaving old iterators pointing to nowhere.
I'm using Visual Studio 2012.
I made a class for a map like this:
classA
{
private:
string a;
string b;
uint32_t start;
uint32_t end;
};
and I defined a map and a function like this:
typedef std::map<uint32_t, classA, std::greater<uint32_t> > ClassAMap;
typedef ClassAMap::iterator ClassAMapIterator;
ClassAMap classAMap;
void lowerBoundTest(ClassAMap &classAMap)
{
uint32_t test = 0;
ClassAMapIterator it;
cin >> hex >> test;
it = classAMap.lower_bound(test);
cout << "lower_bound of " << test << ": "
<< it->first << endl;
}
then I got this error when dereferencing iterator of the map.
Debug Assertion Failed!
Program: C:\Windows\system32\MSVCP110D.dll
File: C:\program files (x86)\microsoft visual studio 11.0\vc\include\xtree
Line: 137
Expression: map/set iterator not dereferencable
For information on how your program can cause an assertion failure,
see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
I don't get any error message when I define a map like this:
typedef std::map<uint32_t, classA> ClassAMap;
typedef ClassAMap::iterator ClassAMapIterator;
But I need to put a greater<> function for purpose.
How can I get rid of this assertion failure?
lower_bound will return the iterator equal to the map's end() when the item you're searching for isn't in the map, and it's insertion point would be at the end of the map. Since end() is one past the end of the map, it doesn't point to a valid element of the map. Trying to dereference it is an error. Be lucky that you were running this in Debug mode with a checked iterator, otherwise you'd have just gotten undefined behavior instead of a nice error message.
The reason it changes when you order the map without greater is that it changes the order of the map; lower_bound is now returning begin() instead of end(), which is a valid element.
To see whether the element was found in the map, you should use equal_range instead of lower_bound and check that the two iterators are not equal. The first of the two is identical to what lower_bound returns.
I am getting all kinds of errors when passing my array to this function. The function is suppose to have the user enter a name and a score and store them in 2 seperate arrays, one for the names, one for the scores. I believe I have to use pointers but have no idea on how to use them. I don't want the answer, just a push in the right direction. Here is the code:
#include <iostream>
int InputData(int &, char, int);
using namespace std;
int main()
{
char playerName[100][20];
int score[100];
int numPlayers = 0;
InputData(numPlayers, playerName, score);
return 0;
}
int InputData(int &numPlayers, char playerName[][20], int score[])
{
while (numPlayers <= 100)
{
cout << "Enter Player Name (Q to quit): ";
cin.getline(playerName, 100, ā\nā);
if ((playerName[numPlayers] = 'Q') || (playerName[numPlayers] = 'q'))
return 0;
cout << "Enter score for " << playerName[numPlayers] <<": ";
cin >> score[numPlayers];
numPlayers++;
}
}
Ok, I made some more changes and the errors are less, must be getting close, Lol!
This looks like a school assignment and I applaud you for not asking for the answer. There are several ways to do it, but you are already fairly close in the approach that you are using. When you pass an array reference, you do not want to include the length of the array. For example, the parameter int score[100] should be int score[]. The exception, especially in your scenario, is with multidimensional arrays. In this case, you want to use char playerName[][20]. Your function declaration also needs to change to match. Don't forget InputData returns an int. Your declarations and function call are correct; you just need to adjust your function signature.
Keeping the errors aside -
InputData(numPlayers, playerName, score, size);
// ^^^^ size is no where declared
// resulting Undeclared indentifier error
Prototype mentions of taking 3 arguments but calling the function passing 4 parameters.
Hint regarding errors:
An 1D array decays to a pointer pointing to first element in the array while passing to a function.
A 2D array decays to a pointer pointing to the 1D array ( i.e., T[][size] ) while passing to a function.
Return type of main() should be int.
It seems with the given hints you corrected most of the errors. But you forgot to change the prototype. So, change -
int InputData(int &, char, int);
to
int InputData(int &, char[][20], int[]);
Why aren't you using std::string array for player names ? Use it and remove rest of the errors. Good luck.