I am trying to understand what I am doing wrong when attempting to dynamically allocate the 2D array "allWordMultiArray" and assign values to it.
I've been reading a lot of articles online (and in Stackoverflow in particular) and tried to implement it in a lot of ways but unsuccessfully. using C++ 14.
So, the following code creates a warning of "Using uninitialized memory '*allWordMultiArray[i]'".
Obviously, when trying to cout the values in the 2D array it prints garbage.
Can someone point to me what the problem is?
Here's a summary of the code:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
const int letters = 26;
int main() {
....
int numWords, pos;
string input;
int** allWordMultiArray;
cin >> numWords;
allWordMultiArray = new int* [numWords];
for (int i = 0; i < numWords; i++) {
cin >> input;
allWordMultiArray[i] = new int[letters];
for (unsigned long int j = 0; j < input.size(); j++)
{
pos = (input[j] - 'a');
//Here is the problem. Garbage values
allWordMultiArray[i][pos]++;
}
}
return 0;
}
Your help is very much appreciated.
This line:
allWordMultiArray[i] = new int[letters];
does allocate memory for an array, but the values in the array are indeterminate. Reading from these values, like here:
allWordMultiArray[i][pos]++;
will invoke undefined behavior.
Just initialize the array when you allocate it:
allWordMultiArray[i] = new int[letters] {};
// ^^
Related
Assume the following numbers are inputed in VC++ Console(separate with a space). N maybe 10, 20 or 100, it is uncertain.
1 2 3 4 ... N [Enter]
The number of inputs is uncertain, maybe 10, or 20. After I press the Enter key, how put these numbers into an Array?
array[0]=1; array[1]=2; ...
How to implement that with C++ code?
(The number of inputs is uncertain!)
As PeterT pointed out, If you don't know the size of the array ahead of time, you'll have to use dynamic memory allocation. Luckily, the STL has a container that does it for you.
You can use std::vector for that job.
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
int main() {
std::string nums; // the numbers in the format "1 2 3 4 10 -20"
std::getline(std::cin,nums);
std::stringstream stream(nums);
int n;
std::vector<int> vec;
while(stream >> n) {
vec.push_back(n);
}
return 0;
}
(code is based on Abdulla Al Sun's answer.)
This is an O(n) (linear complexity) solution.
If you want to convert it in to an actual array, you can do:
int array[vec.size()];
std::copy(vec.begin(), vec.end(), array);
Another approach is to figure out how many elements the user inputted by storing his input in a string, and counting the tokens.
Then you know how big of an array you need.
unsigned int getSize(std::string s) {
unsigned int size = 0;
std::stringstream ss(s);
int in;
while (ss >> in)
++size;
return size;
}
int main() {
std::string nums; // the numbers in the format "1 2 3 4 10 -20"
std::getline(std::cin,nums);
const unsigned int size = getSize(nums);
int array[size];
std::stringstream stream(nums);
int n;
for(unsigned int i = 0; stream >> n && i < size; ++i) {
array[i] = n;
}
return 0;
}
This is an O(2n) (linear complexity) solution.
My code assumes that the compiler allows variable array size. If it doesn't, use:
int* array = new int[size];
...
delete[] array;
To utilize RAII, wrap it in a struct like so:
struct DynArr {
int* data;
unsigned int size;
DynArr(const unsigned int size) :
size(size) {
data = new int[size];
}
~DynArr() {
delete[] data;
}
};
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int array[1000]; // your heighest input range
vector<int> numbers;
int main() {
string nums; // the numbers in the format "1 2 3 4 10 -20"
getline(cin,nums);
stringstream stream(nums);
int i = 0;
int n;
while(stream >> n){
array[i++] = n;
numbers.push_back(n);
}
// The number of integers in array is i. You can do anything with this number.
// numbers contains the input numbers.
return 0;
}
I have added vector after getting PeterT's idea. You can add vector for not setting the static size of array.
Try this code. The header of stringstream is sstream. I have compiled in in codeblocks, I think this will work on VC++ compiler too.
I'm going to steal Abdulla's code and make a couple slight modifications.
#include <iostream>
#include <string>
#include <sstream>
#include <cstring.h> // for memcpy
//using namespace std; frowned on. polutes global namespace
//the highest input range is undefined, so this isn't safe
//int array[1000]; // your heighest input range
int main() {
int max=10;
int * array = new int[max];// allow resizing of array by dynamically allocating
std::string nums; // the numbers in the format "1 2 3 4 10 -20"
std::getline(std::cin,nums);
std::stringstream stream(nums);
int i = 0;
while(stream){
if (i==max)
{
int * temp = new int[max*2];// note statistical analysis has found
//1.5 is generally a better multiplier
memcpy(temp, array, max*sizeof(array[0]));
// note do not use memcpy for copying complex data. It is too stupid.
delete array; // release memory of old array
array = temp; // replace old array with new array
max*=2;
}
int n;
stream>>n;
array[i++] = n;
}
// The number of integers in array is i. You can do anything with this number.
delete array; // all done. clean up.
return 0;
}
The really smart way is to use a std::vector. Odds are really good that this is going to be frowned on by the marker, so make your own resizable array class. With a class you can easily take advantage of RAII and automate the clean-up so it's exception safe.
i got stuck with dynamic arrays. I want to read ints from a text file and store them into the array. I need a push_back and size function but cant use the STL from vector. I tried to do a push_back function but i need to use the size function for this. For the size function i thought of going through the array and increment a counter for each element, but how do i stop the loop, e.g. for (int i = 0; i < d_array.end(); i++), to use .end() I need to include <array> ?
Thanks for hints.
my code so far:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
int* d_array = 0;
const string filename = "test.txt";
int s = 0;
int counter = 0;
fstream f;
f.open(filename, ios::in);
if (f){
while (f >> s){
counter += 1;
}
}
d_array = new int[counter];
if (f){
while (f >> s){
d_array.push_back(s);
}
f.close();
}
for (int i = 0; i < d_array.size(); i++){
cout << d_array[i] << "\n";
}
void push_back(int value){
int d_size = d_array.size();
int* d2_array = 0;
d2_array = new int[d_size + 1];
d_array = d2_array;
d_array[d_size] = value;
delete[] d2_array;
}
int size() const{
}
}
You're asking the wrong question. You're trying to solve the question
How can I find the length of a dynamically allocated array, given just the pointer to its beginning
which has no solution in general — but the question you actually need to solve is
How do I make a data structure that contains a dynamically allocated array so that I can obtain the size of the array?
which has a really simple solution, once you stop getting hung up on the question you're focusing on....
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdio>
#include <stdlib.h>
using namespace std;
int gradeExam(string answerKeyARR[]);
int main()
{
const int QUESTIONS = 10;
const int MAX_STUDENTS = 250;
ifstream inFile;
ofstream outFile;
inFile.open("grade_data.txt");
outFile.open("grade_report.txt");
string ansKey;
inFile >> ansKey;
string answerKeyARR[QUESTIONS];
//Loop for storing each answer into an array rather than all in a single string.
for (int j = 0; j < QUESTIONS; j++)
{
answerKeyARR[j] = ansKey.substr(j,1);
}
int i = 0;
int numStudents = 0;
string studentAnswers[MAX_STUDENTS];
//Loop to read in all answers into array and count number of students.
while (!inFile.eof())
{
inFile >> studentAnswers[i];
numStudents++;
i++;
}
//WHY DOES IT CRASH HERE?!
string studentAnswersARR[numStudents][QUESTIONS];
for (int k = 0; k < numStudents; k++)
{
for (int l = 0; l < QUESTIONS; l++)
{
studentAnswersARR[k][l] = studentAnswers[l].substr(l,1);
cout << studentAnswersARR[k][l];
}
}
inFile.close();
outFile.close();
return 0;
}
Okay, so basically once it gets to the part where it's removing the substring, it crashes. It works perfectly fine for retrieveing the answerkey answers, so why the hell is it crashing when it gets to this point? This is still a WIP for basic coding 2.
Also, when I change variable 'l' to, say, position 0, it works. What gives?
There are multiple issues with your code that may cause problems.
First, your input loop is not bounded properly. It should stop at MAX_STUDENTS, but you fail to check for this limit.
Second, do not use eof() to check for the end of file. There are many posts on SO discussing this.
while (!inFile && i < MAX_STUDENTS)
{
inFile >> studentAnswers[i];
numStudents++;
i++;
}
The next issue is the line you highlighted in your question. It probably crashes due to stack space being exhausted. But the code you have uses a non-standard C++ extension, and once you do that, then the rule as to what that line really does internally is up to the compiler vendor.
So to alleviate this with using standard C++, the following can be done:
#include <vector>
#include <string>
#include <array>
//...
std::vector<std::array<std::string, QUESTIONS> >
studentAnswersARR(numStudents);
im doing simple genetic algorithm uniform crossover operation . for that im using two arrays as parent and mother.i want concatenate the childs for getting the offsprings(childs).
i have problem in adding the arrays .any help plssss.i did it ubuntu
#include<iostream>
#include <fstream>
#include <algorithm>
#include<vector>
using namespace std;
int main()
{
int P[ ]={3,7,6,5,2,4,1,8};
int N[ ]={8,6,7,2,5,3,4,1};
int r= (sizeof(P)/sizeof(*P)) ;
int s= (sizeof(N)/sizeof(*N));
int val=r/2 ;
int t1[val],t2[val],t3[val],t4[val],n=0,p=0;
for(int m=0;m< val;m++)
{
t1[n]=P[m];
t2[n]=N[m];
n++;
}
for(int x=val;x< r;x++)
{
t3[p]=P[x];
t4[p]=N[x];
n++;
}
int* child=new int [val+val];
copy(t1,t1+val,child);
copy(t3,t3+val,child+val);
cout << child;
}
return 0;
}
This part is wrong:
int t1[val], t2[val], t3[val], t4[val]
You can only use constant values to declare the size of arrays.
You can either use a std::vector or dynamically allocate memory for the t-arrays.
std::vector<int> t1(val);
std::vector<int> t2(val);
for(int m = 0; m < val; m++)
{
t1[n] = P[m];
t2[n] = N[m];
n++;
}
There seem to be multiple errors in your code.
Variable length arrays are at present not supported in C++.
int val=r/2 ;
int t1[val]; // Not OK
In the second for loop I guess you meant p++ instead of n++;
Instead of manually doing all the memory allocation - deallocation, you should use std::vectors
cout << child; // This outputs the address of the pointer, not the entire array.
I have been working at this for over 2 hours. I have isolated my problem to one piece of code.
The problem is with my array. It is outputting really big negative values. The values I am feeding into the array are correct. I am experienced with java, but this is my first C++ program.
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main(){
string inputString;
cin >> inputString;
cout << inputString << endl;
int mainArray[10];
for(int x = 0; x < inputString.length(); x++){
int valFound = inputString[x]-48; //minus 48 to change from ascii to int
mainArray[valFound]++;
cout << mainArray[valFound];
}
return 0;
}
Any help would be much appreciated, this is making me crazy.
Your array is being default initialized. Default initialization of the type int leaves it "with garbage". You need to initialize it to 0 explicitly:
int mainArray[10] = {0};
This is because arrays need to be initialized. Add this to your code:
for (int i = 0 ; i != 10 ; i++) {
mainArray[i] = 0;
}
Alternatively, you can use memset:
memset(mainArray, 0, sizeof(mainArray));