Variable Value Changes By Itself - c++
I've been pretty confused while programming before, but this one takes the cake. Basically I set the value in one for loop, and in the following iteration it changes to the value of the next one.
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < numWords[i]; ++j) //numWords [0] = 9, numWords [1] = 7
{
stb[i][j].word = const_cast<char*>(is (j + 1,1).c_str()); //is(int,length[opt]) converts int to string, c_str() returns const char *, but I need char *
cout << is(j+1,1) << ' ' << stb[i][j].word << '\n';
}
}
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < numWords [i]; ++j)
{
cout << stb[i][j].word << ' ';
}
cout << '\n';
}
Output:
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
1 1
2 2
3 3
4 4
5 5
6 6
7 7
7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7
My only guess now is something with the const, but it doesn't make sense why it would keep changing all previous array elements...
This is pretty simple. Your program has undefined behaviour (if my assumptions about is() are correct).
is(int, length) returns a std::string by value. You get a pointer to some internal structure in that string by using c_str(). This string is then destructed at the end of the full-expression. This destruction invalidates the pointers that you obtained from c_str().
This means that you fill up the array with pointers to invalid memory. You then read from these pointers to print out the contents of the array. Reading from invalid memory results in undefined behaviour.
A possible explanation for the observed behaviour is this:
Each string that is returns reuses the same memory. In the first loop you read from the memory before it has been overwritten by another call to is, and so you get the correct value. In the second loop you read from the memory after it has been overritten, and so you get the final value in the array.
Related
How to relocate an element in one array in C++
I took this interview question and I failed, so I'm here to not fail again! I have an array of int with size 16 and a 5 < givenIndex < 10. I have to take the element in this index a print every possible array (there are 16) by moving the element at givenIndex through every position in array and pushing rest of elements. For example: int array[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; int givenIndex = 6; Since array[givenIndex] = 7, I need to move 7 to every possible position and print that array. [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] [7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16] [1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16] [1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16] And that's for 16 cases. What I was trying was: for(int i = 0;i<16;i++){ array[i] = array[indexInsercion] if (i<indexInsert){ //right shift array[i] = array[i+1] }else if(i == indexInsert){ //no shift }else{ //left shift array[i] = array[i-1] } } Can I get some help?
We can only guess what the interviewer expected to see. If I was the interviewer I would like to see that you keep things simple. This is code I think one can expect to be written from scratch in an interview situation: #include <iostream> #include <array> template <size_t size> void print_replaced(const std::array<int,size>& x,size_t index){ for (int i=0;i<size;++i){ for (int j=0;j<i;++j) { if (j == index) continue; std::cout << x[j] << " "; } std::cout << x[index] << " "; for (int j=i;j<size;++j) { if (j == index) continue; std::cout << x[j] << " "; } std::cout << "\n"; } } int main() { std::array<int,16> x{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; print_replaced(x,6); } It is a first approach at the problem, with a loop that prints 16 different combinations of the array elements. Printing each line follows simple logic: We print all elements before the one that should be replaced, then the one that should be shuffled, then the remaining elements. It is simple, but wrong. Its output is: 7 1 2 3 4 5 6 8 9 10 11 12 13 14 15 16 1 7 2 3 4 5 6 8 9 10 11 12 13 14 15 16 1 2 7 3 4 5 6 8 9 10 11 12 13 14 15 16 1 2 3 7 4 5 6 8 9 10 11 12 13 14 15 16 1 2 3 4 7 5 6 8 9 10 11 12 13 14 15 16 1 2 3 4 5 7 6 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 8 7 9 10 11 12 13 14 15 16 1 2 3 4 5 6 8 9 7 10 11 12 13 14 15 16 1 2 3 4 5 6 8 9 10 7 11 12 13 14 15 16 1 2 3 4 5 6 8 9 10 11 7 12 13 14 15 16 1 2 3 4 5 6 8 9 10 11 12 7 13 14 15 16 1 2 3 4 5 6 8 9 10 11 12 13 7 14 15 16 1 2 3 4 5 6 8 9 10 11 12 13 14 7 15 16 1 2 3 4 5 6 8 9 10 11 12 13 14 15 7 16 There is one line that appears twice and the last line is missing. As an interviewer I would not be surprised that the first attempt does not produce correct output. I don't care about that. Thats not a minus. What I would care about is how you react on that. Do you know the next steps? Do you have a strategy to fix the wrong output? Or do you just panic because you didn't manage to write the correct code on the first attempt? This is what I would like to check in an interview and then thats the end of the exercise. I want to ask more different questions rather than giving you the time to fix all mistakes and write correct well tested code, because I know that this takes more time than we have in the interview. I'll leave it to you to fix the above code ;)
Here's a quick stab at it. Basically just keep track of where the given index should go and print it there as well as skip the original position it would be in. #include <iostream> int main() { int array[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; int givenIndex = 6; for (int p = 0; p <= 16; ++p) { if (p != givenIndex) { std::cout << "["; for (int i = 0; i < 16; ++i) { if (i == p) { if (i > 0) { std::cout << ","; } std::cout << array[givenIndex]; } if (array[i] != array[givenIndex]) { if (i > 0 || p == 0) { std::cout << ","; } std::cout << array[i]; } } if (p == 16) { std::cout << "," << array[givenIndex]; } std::cout << "]\n"; } } } Output: [7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16] [1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16] [1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16] [1,2,3,7,4,5,6,8,9,10,11,12,13,14,15,16] [1,2,3,4,7,5,6,8,9,10,11,12,13,14,15,16] [1,2,3,4,5,7,6,8,9,10,11,12,13,14,15,16] [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] [1,2,3,4,5,6,8,7,9,10,11,12,13,14,15,16] [1,2,3,4,5,6,8,9,7,10,11,12,13,14,15,16] [1,2,3,4,5,6,8,9,10,7,11,12,13,14,15,16] [1,2,3,4,5,6,8,9,10,11,7,12,13,14,15,16] [1,2,3,4,5,6,8,9,10,11,12,7,13,14,15,16] [1,2,3,4,5,6,8,9,10,11,12,13,7,14,15,16] [1,2,3,4,5,6,8,9,10,11,12,13,14,7,15,16] [1,2,3,4,5,6,8,9,10,11,12,13,14,15,7,16] [1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,7]
If the expectation is to just print the elements of array in the given order: Keep the track of current index of array element to be print, say indx - If the position of current element processing is equal to row number then print the element at givenIndex. If indx is equal to givenIndex skip it and print indx + 1 element, otherwise print element at indx and increase indx by 1. Implementation: #include <iostream> #include <array> int main() { std::array<int, 16> array = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; std::size_t givenIndex = 6; for (std::size_t i = 0, indx = 0; i < array.size(); indx = 0, ++i) { std::cout << '['; for (std::size_t j = 0; j < array.size(); ++j) { if (j == i) { std::cout << array[givenIndex] << ','; continue; } if (indx == givenIndex) { ++indx; } std::cout << array[indx++] << ','; } std::cout << ']'; std::cout << '\n'; } return 0; } Output: # ./a.out [7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,] [1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16,] [1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16,] [1,2,3,7,4,5,6,8,9,10,11,12,13,14,15,16,] [1,2,3,4,7,5,6,8,9,10,11,12,13,14,15,16,] [1,2,3,4,5,7,6,8,9,10,11,12,13,14,15,16,] [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,] [1,2,3,4,5,6,8,7,9,10,11,12,13,14,15,16,] [1,2,3,4,5,6,8,9,7,10,11,12,13,14,15,16,] [1,2,3,4,5,6,8,9,10,7,11,12,13,14,15,16,] [1,2,3,4,5,6,8,9,10,11,7,12,13,14,15,16,] [1,2,3,4,5,6,8,9,10,11,12,7,13,14,15,16,] [1,2,3,4,5,6,8,9,10,11,12,13,7,14,15,16,] [1,2,3,4,5,6,8,9,10,11,12,13,14,7,15,16,] [1,2,3,4,5,6,8,9,10,11,12,13,14,15,7,16,] [1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,7,] If the expectation is to alter the order of elements in the array and then print the array: First move the element at givenIndex to the 0th index of array and then - Print array In every iteration swap the current element with its next element in the array and print it. Implementation: #include <iostream> #include <array> void print_array (std::array<int, 16>& array) { std::cout << '['; for (std::size_t indx = 0; indx < array.size(); ++indx) { std::cout << array[indx] << ','; } std::cout << ']'; std::cout << '\n'; } void rearrange_array_elem (std::array<int, 16>& array, std::size_t givenIndx) { // move the element at givneIndx to first position in array for (std::size_t j = givenIndx; j > 0; --j) { std::swap (array[j], array[j - 1]); } // print array print_array (array); for (std::size_t indx = 0; indx < array.size() - 1; ++indx) { // swap current element with its next element std::swap (array[indx], array[indx + 1]); print_array (array); } } int main() { std::array<int, 16> array = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; std::size_t givenIndex = 6; rearrange_array_elem (array, givenIndex); return 0; } Output: # ./a.out [7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,] [1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16,] [1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16,] [1,2,3,7,4,5,6,8,9,10,11,12,13,14,15,16,] [1,2,3,4,7,5,6,8,9,10,11,12,13,14,15,16,] [1,2,3,4,5,7,6,8,9,10,11,12,13,14,15,16,] [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,] [1,2,3,4,5,6,8,7,9,10,11,12,13,14,15,16,] [1,2,3,4,5,6,8,9,7,10,11,12,13,14,15,16,] [1,2,3,4,5,6,8,9,10,7,11,12,13,14,15,16,] [1,2,3,4,5,6,8,9,10,11,7,12,13,14,15,16,] [1,2,3,4,5,6,8,9,10,11,12,7,13,14,15,16,] [1,2,3,4,5,6,8,9,10,11,12,13,7,14,15,16,] [1,2,3,4,5,6,8,9,10,11,12,13,14,7,15,16,] [1,2,3,4,5,6,8,9,10,11,12,13,14,15,7,16,] [1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,7,]
Trash in operating memory with dynamic arrays
I've tried to make an algorithm, which counts how many numbers are divided without a remainder. Code works, but every time I run it, I'm getting "trash" numbers in my output. I'm using dynamic arrays to solve a problem. #include <iostream> using namespace std; int main() { int N = 30; int *data = new int [N]; for (int i = 0; i < 100; i++) { for (int c = 1; c < N; c++) { if (i % c == 0) { data[c] += 1; } } } for (int k = 1; k < N; k++) { cout << data[k] << endl; } delete [] data; } I've expected to have, at least, what C++ Shell says: http://cpp.sh/6xtc 100 50 34 25 20 17 15 13 12 10 10 9 8 8 7 7 6 6 6 5 5 5 5 5 4 4 4 4 4 , but got in different IDE the same result: 100 11932994 34 25 20 17 15 13 12 620757039 37045 11951945 8 11927896 7 7 7290 158 6 5 5 570425383 37040 11951941 4 11927892 4 1835102827 859059803
You do int *data = new int [N]; And allocate an N-sized array. Then you immediately start trying to increment the values in it: data[c] += 1; But what was in there to begin with? If you want to guarantee that all the values will be initialized to 0, per this answer you can allocate your array with: int *data = new int [N](); // ^^^^ <Obligatory "you should just be using std::vector!" comment here.\> (But actually though, vectors would make this way easier and avoid this issue entirely)
data[c] += 1; You add something to an uninitialized value. data[c] was not necessarily 0 before that. new does not initialize a dynamic array to zero. Quit all new/delete and use std::vector<>. And, do learn to use the debugger - really helpful in this case.
Why is this code outputting so many numbers? [duplicate]
This question already has answers here: ARRAYSIZE C++ macro: how does it work? (7 answers) c++ sizeof(array) return twice the array's declared length (6 answers) Closed 3 years ago. Starting with two arrays a and b, I am trying to output a matrix c with dimensions sizeof(a) and sizeof(b), whose entries are the product of every pair of the Cartesian product of a and b. Theses products are also stored in a two dimensional array c. My code is below. #include <iostream> #include <string> int main() { int a[]= { 1,2,3,4,5,5 }; int b[]= { 1,23,2,32,42,4 }; int c[sizeof(a)][sizeof(b)]; for (int i = 0; i < sizeof(a); i++) { for (int j = 0; j < sizeof(b); j++) { c[i][j] = a[i]* b[j] ; std::cout << c[i][j] << " "; } std::cout << "\n"; } return 0; } My output is: 1 23 2 32 42 4 -858993460 -858993460 1 2 3 4 5 5 -858993460 16710224 15543422 1 2161328 2122464 16710312 15543008 196436084 15536213 2 46 4 64 84 8 -1717986920 -1717986920 2 4 6 8 10 10 -1717986920 33420448 31086844 2 4322656 4244928 33420624 31086016 392872168 31072426 3 69 6 96 126 12 1717986916 1717986916 3 6 9 12 15 15 1717986916 50130672 46630266 3 6483984 6367392 50130936 46629024 589308252 46608639 ... This is just a small part of the output.
sizeof(a) is not the length of the array, it is the number of bytes required to store it. Since the element type of the array is larger than one byte each, the numbers are different.
C++ Printing Contents of array backwards One incorrect digit
As part of a program I'm trying to print the contents of an array in reverse order. It is working fine except for one value and I can't figure out why. I haven't gotten onto functions yet so I haven't used them in my code here is the snippet case 7: for (int i = 11; i != -1; i--)// The variable i is initialised to 11. While i is not equal to -1 decrement i by 1. { infile >> list[i];//Read in values for array from data.dat cout << list[i] << " ";// Outputting the array in reverse order. outfile << "The array in reverse order is: " << list[i] << " " << endl;// Outputting the array in reverse order to file. } cout << endl; break; The array is filled with the following numbers 8 16 12 6 16 4 8 10 2 16 12 6 The expected output is: 6 12 16 2 10 8 4 16 6 12 16 8 The output I'm getting is: 6 12 16 2 10 8 4 16 6 12 6 8 Any help appreciated
The right way to reverse an iterator is to shift it down by one. Forward: T a[N]; for (std::size_t i = 0; i != N; ++i) { consume(a[i]); } Backward: T a[N]; for (std::size_t i = 0; i != N; ++i) { std::size_t const ri = N - i - 1; // ^^^ consume(a[ri]); } You can write a loop where you actually decrement the loop variable directly, but it's awkward since you either have to use signed integers or otherwise do an additional - 1 when using the index, and it's altogether unnatural, hard to read and easy to get wrong. I'd much rather recommend always using the forward-moving loop as shown here and compute the reverse iterator separately. Incidentally, this logic is already encapsulated in the iterator wrapper std::reverse_iterator, which is build from a normal, bidirectional moving iterator but decrements by one when being dereferenced. You can either reverse a sequence yourself by using make_reverse_iterator, or by using the free rbegin/rend functions: #include <iterator> T a[N]; for (auto rit = std::crbegin(a); rit != std::crend(a); ++rit) { consume(*rit); }
C++ passing pointer to vector element instead of array pointer
I think the following code snippet is perfectly legal (it builds anyway on MS Visual Studio 2008, C++). I use it to link to a 3rd party library. But I think because I am passing a pointer to a vector element instead of a regular pointer that the 3rd party library function expects, I get a run-time error Invalid parameter detected by C-runtime library What am I doing wrong here? std::vector<int> vec_ints(27,0); std::vector<double> vec_doub(27, 0.); for(int i = 0; i < n; ++i) { //-Based on my understanding when i >=27, STL vectors automatically reallocate additional space (twice). vec_ints[i] = ...; vec_doub[i] = ...; } const int* int_ptr = &vec_ints[0]; const double* doub_ptr = &vec_doub[0]; //-Func is the 3rd party library function that expects a const int* and const double* in the last 2 arguments. func(...,...,int_ptr,doub_ptr); But running this after building on MS Visual Studio 2008 (Windows Vista), leads to run-time error as mentioned above, viz., Invalid parameter detected by C runtime library Haven't tested this on Linux yet and I sure would like to avoid copying the contents of the vector into an array just for this. Any ideas what is going on? Further edit to confirm usage of Nick and Chris' recommendation and to continue discussion with Vlad et al; here's a code snippet: #include <iostream> #include <vector> int main() { for(int i=2; i<6; ++i) { int isq = i*i; std::vector<int> v; v.reserve(4); for(int j=0; j<isq; ++j) { v.push_back(j); } std::cout << "Vector v: size = " << v.size() << " capacity = " << v.capacity() << "\n"; std::cout << "Elements: \n"; for(int k=0; k<v.size(); ++k) { std::cout << v.at(k) << " "; } std::cout << "\n\n"; } return 0; } Gives output: Vector v: size = 4 capacity = 4 Elements: 0 1 2 3 Vector v: size = 9 capacity = 16 Elements: 0 1 2 3 4 5 6 7 8 Vector v: size = 16 capacity = 16 Elements: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Vector v: size = 25 capacity = 32 Elements: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 So atleast for the usage in this context, where no explicit resize is used, it seems to work as intended/expected.
std::vector<T> expands if you are adding elements using std::vector<T>::push_back(T &), std::vector<T>::insert(iterator, T &) (thanks K-ballo) or explicitly calling std::vector<T>::resize(size_t). Otherwise, it doesn't expand. std::vector<int> vec_ints; vec_ints.reserve(27); std::vector<double> vec_doub; vec_doub.reserve(27); for(int i = 0; i < n; ++i) { vec_ints.push_back(...); vec_doub.push_back(...); } const int* int_ptr = &vec_ints[0]; const double* doub_ptr = &vec_doub[0]; func(...,...,int_ptr,doub_ptr); You want something like that
No, vector doesn't expand automatically. You need to expand it yourself: if (n > 27) vec_ints.resize(n, 0); etc.
Why not just create the vectors with the correct size to begin with? Like so: std::vector<int> vec_ints(n,0); std::vector<double> vec_doub(n, 0.);