How to dynamically allocate data struct array with nullptr and struct members? - c++

I am newly to programming with c++ and I am trying to allocate memory for array of struct. The problem is I don't know the size of elements inside it at compile time. I want the "empty" part to be allocated with null pointers. I run this code below, but there is no the output I expected to be. Could somebody help me?
#include <iostream>
using namespace std;
typedef struct ones{
int a;
int b;
}ones;
ones** twoes = nullptr;
int main()
{
cout<<"Hello World";
for(int i = 0; i < 5; i++)
{
twoes[i]= nullptr;
}
cout<< "i dont get HERE" << endl;
for(int i = 0; i < 5; i++)
{
twoes[i]= new ones;
twoes[i]->a = 2;
cout<< twoes[i]->a <<endl;
}
return 0;
}

Related

Debug Assertion Failed: Expression vector subscript out of range

I dont understand why it says subscript out of range when I have reserved the space in the vector. I have created a short form of my code to explain what the problem is better:
#include <vector>
#include <string>
#include <thread>
#include <iostream>
using namespace std;
class A {
public:
vector<vector<string>> foo;
thread* aThread;
A() {
foo.reserve(10); //makes sure we have space...
aThread = new thread([this]() {
for (int i = 0; i < 10; i++) {
foo[i].push_back("Hello"); // Debug assertion failed. :(
}
});
}
};
int main()
{
A a;
a.aThread->join();
for (int i = 0; i < 10; i++) {
for (int j = 0; j < a.foo.size(); j++) {
cout << a.foo[i][j] << " ";
}
cout << endl;
}
return 0;
}
Here it gives the error as soon as I am trying to add the element into my foo vector inside the thread. I cannot figure out what is wrong. Please help.
foo.reserve(10)
Reserves space for elements in foo, but it does not populate any of the elements with an empty std::vector.
You can change it to:
foo.resize(10);
Which will reserve the space and create the empty vector< string > elements, so that you can access them.

How to copy char array of a structure into another char array of a structure?

#include <iostream>
using namespace std;
struct stud
{
char name[10];
int id;
};
int input(stud a[], int size)
{
for(int i=1; i<=size; i++)
{
cout<<"name = ";
cin>>a[i].name;
cout<<"id = ";
cin>>a[i].id;
}
cout<<endl;
return 0;
}
int output(stud a[], int size)
{
for(int i=1; i<=size; i++)
{
cout<<"name = "<<a[i].name<<" ";
cout<<"id = "<<a[i].id<<" ";
}
cout<<endl;
return 0;
}
int copy(stud a[], stud x[], int size)
{
for(int i=1; i<=size; i++)
{
x[i].name=a[i].name;
x[i].id=a[i].id;
}
output(x,size);
cout<<endl;
return 0;
}
int main()
{
struct stud s[3], x[3];
input(s,3);
output(s,3);
copy(s,x,3);
return 0;
}
In this program the statement in function copy x[i].name =a[i].name; is not copying contents from 1 structure object to another. I have tried to put this statement in for loop for(int j=1;j<=10;j++) x[i].name[j] =a[i].name[j]; but still not working.
please suggest what should be changed or some alternatives for this.
i'll be very thankful to you for this.
regards,
umar
Either using a loop to copy each character in the name field or using thestrcpy function from <cstring> header works.
int copy(stud a[], stud x[], int size) {
for(int i = 1; i <= size; i++) {
// for(unsigned j = 0; j < 10; j++) {
// x[i].name[j] = a[i].name[j];
// }
strcpy(x[i].name, a[i].name);
x[i].id = a[i].id;
}
output(x, size);
cout << endl;
return 0;
}
But since you tagged this as c++, consider using std::string instead of a char array, unless you have a particular reason for using a char array. In that case x[i].name = a[i].name would have worked just fine and you could also use the standard algorithm library for copy. Also, using std::array instead of a raw C array for you "array of structures" might be a better option (does not degenerate into a pointer like a regular C array does).
Evrey single one of your loops is wrong, because in C++ arrays start at zero. So not
for(int i=1; i<=size; i++)
instead
for(int i=0; i<size; i++)
You cannot copy arrays by writing a = b;. Since your arrays are really strings there's a built in function strcpy to copy strings.
strcpy(x[i].name, a[i].name);
If you use = to copy struct, the char array inside that struct will be copied. You don't need to do anything more.
#include <iostream>
using namespace std;
typedef struct{
char name[10];
} type_t;
int main() {
type_t a = {"hihi"};
type_t b;
b = a;
a.name[0] = 'a';
cout<<a.name<<endl;
cout<<b.name<<endl;
return 0;
}
output:
aihi
hihi
ideone: https://ideone.com/Zk5YFd

How to pass Dynamic Array by reference C++

I'm having trouble understanding how to pass a dynamic array by reference in C++.
I've recreated the problem in this small isolated code sample:
#include <iostream>
using namespace std;
void defineArray(int*);
int main()
{
int * myArray;
defineArray(myArray);
/** CAUSES SEG FAULT*/
//cout<<(*(myArray)); //desired output is 0
return 0;
}
void defineArray(int*myArray)
{
int sizeOfArray;
cout<<"How big do you want your array:";
cin>>sizeOfArray;
/** Dynamically allocate array with user-specified size*/
myArray=new int [sizeOfArray];
/** Define Values for our array*/
for(int i = 0; i < sizeOfArray; i++)
{
(*(myArray+i))=i;
cout<<(*(myArray+i));
}
}
myArray is passed by value itself, any modification on myArray (such as myArray=new int [sizeOfArray];) has nothing to do with the original variable, myArray in main() is still dangled.
To make it passed by reference, change
void defineArray(int*myArray)
to
void defineArray(int*& myArray)
This solution is hopelessly complicated. You don't need new[], pointers or even a reference parameter. In C++, the concept of "dynamic arrays" is best represented by std::vector, which you can just just use as a return value:
#include <iostream>
#include <vector>
std::vector<int> defineArray();
int main()
{
auto myArray = defineArray();
if (!myArray.empty())
{
std::cout << myArray[0] << "\n";;
}
}
std::vector<int> defineArray()
{
int sizeOfArray;
std::cout << "How big do you want your array:";
std::cin >> sizeOfArray;
std::vector<int> myArray;
for (int i = 0; i < sizeOfArray; i++)
{
myArray.push_back(i);
std::cout<< myArray[i] << "\n";
}
return myArray;
}
push_back will work intelligently enough and not allocate new memory all the time. If this still concerns you, then you can call reserve before adding the elements.

Referencing Elements of Class Arrays using C++

I am trying to switch the elements of a class array using pointers. It is not outputting what I want. I tried using pointers in the function, but it's not allowed. It's also not allowed to call the function onto the class object without using a pointer, since I declared the class object using a double pointer. I am not using this method simply to solve a small problem, but just to practice using this method for more difficult problems.
Here is my code:
#include <iostream>
#include <algorithm>
using namespace std;
class thing{
public:
int index;
int value;
thing();
private: int number;
};
thing::thing()
{
number = 0;
}
void arrange(thing array[]){
for(int i=0; i<19; ++i){
if(array[i].value<array[i+1].value){
swap(array[i], array[i+1]);
arrange(array);
}
}
}
int main(){
thing** things = new thing*[20];
for (int i=0; i < 20; ++i)
{
things[i] = new thing(); // default constructor
things[i]->index = i;
things[i]->value=rand() % 100;
}
cout << "The random array is: " << endl;
for(int i=0;i<20;++i){
cout << things[i]->value << endl;
}
arrange(*things);
cout << "The arranged array is: " << endl;
for (int i=0; i < 20; ++i)
{
cout << things[i]->value << endl;
}
return 0;
}
When you call arrange(*things), you're just passing the first element of things to the function, not the array. It should be array(things). Then the arrange function should be written to use pointers:
void arrange(thing* array[]){
for(int i=0; i<19; ++i){
if(array[i]->value<array[i+1]->value){
swap(array[i], array[i+1]);
arrange(array);
}
}
}
Here you create an array of pointers to thing:
thing** things = new thing*[20];
Here you dereference it and get a pointer to thing which is stored at thing[0]:
arrange(*things);
But this function declaration
void arrange(thing array[])
treats this pointer as an array of thing, so that *things points to it first element, which is absolutely not what it really is.
You should change your arrange() function to use correct type:
void arrange(thing* array[]){
for(int i=0; i<19; ++i){
if(array[i]->value<array[i+1]->value){
swap(array[i], array[i+1]);
arrange(array);
}
}
}
And call it as:
arrange(things);
Regarding using vectors, you don't need to use any pointers at all.
std::vector<thing> things(20);
for (int i=0; i < things.size(); ++i)
{
things[i].index = i;
things[i].value=rand() % 100;
}
arrange(things);
void arrange(std::vector<thing>& array){
for(int i=0; i + 1 < things.size(); ++i){
if(array[i].value<array[i+1].value){
swap(array[i], array[i+1]);
arrange(array);
}
}
}

selection sort array run time error

This is my first time here. I really hope anyone can help me out there. So this is my problem. I keep getting run time error #2 something about a corrupt "arr". But the program runs fine until the end. I can't figure it out.
This is my code:
#include <iostream>
using namespace std;
void main(){
int arr1[3];
int temp;
//INPUT NUMBERS
for (int i=0; i<5;i++)
{
cin>>arr1[i];
}
cout<<endl;
//SORT
for(int c=0;c<5;c++)
{
for (int k=0;k<5;k++)
{
if(arr1[c]<arr1[k])
{
temp=arr1[k];
arr1[k]=arr1[c];
arr1[c]=temp;
}
}
}
for (int m=0; m<5; m++)
{
cout<<arr1[m]<<endl;
}
}
Try this out:
#include <iostream>
using namespace std;
int main()
{
int arr1[5];
int temp;
//INPUT NUMBERS
for (int i = 0; i < 5; i++) {
cin >> arr1[i];
}
cout << endl;
//SORT
for (int c = 0; c < 5; c++) {
for (int k = 0; k < 5; k++) {
if (arr1[c] < arr1[k]) {
temp = arr1[k];
arr1[k] = arr1[c];
arr1[c] = temp;
}
}
}
for (int m = 0; m < 5; m++) {
cout << arr1[m] << endl;
}
}
It compiles properly without any errors. The mistake you had made is in declaring the size of the array. If you want to store 5 in puts, you need to declare an array of size 5. Your code might work, but a good compiler will always give out an error.
The reason being that when you declare an array, you actually create a pointer to the first element of the array. And then, some memory regions are kept for this array, depending on the size. If you try to access an element that is outside these memory regions, you may encounter a garbage value.
Here's your code in ideone.