Something wrong in c++ code - c++

Please what wrong in this code:
#include <iostream>
#include <vector>
unsigned __int32 ConvertToChars(std::vector<int> container, char** pChars)
{
*pChars = (char*)&container[0];
return container.size() * sizeof(int);
}
void ConvertToIntegers(char* chars, short size, std::vector<int>& container)
{
int count = size / sizeof(int);
int* pIntegers = (int*)chars;
for(int i=0; i < count; ++i)
{
container.push_back(*(pIntegers++));
}
}
void Print(const std::vector<int>& container)
{
for(int i=0; i < container.size(); ++i)
{
std::cout << container[i] << std::endl;
}
}
void main()
{
std::vector<int> vec1;
vec1.push_back(1);
vec1.push_back(2);
vec1.push_back(3);
char* buffer = 0;
short bufferSize = ConvertToChars(vec1, &buffer);
std::vector<int> vec2;
ConvertToIntegers(buffer, bufferSize, vec2);
Print(vec2);
char c;
std::cin >> c;
}
function Print prints values:
-572662307
-842150451
-572662307
Thank you!!!

You're copying the container when you pass it to ConvertToChars, then taking a pointer to one of its elements, then seeing the copy go out of scope, which invalidates your pointer.

I don't really understand the point of your program, but part of your problem is in your ConvertToIntegers function, where you make your program interpret a char * as int *.
int* pIntegers = (int*)chars;
for(int i=0; i < count; ++i)
{
container.push_back(*(pIntegers++));
}
You're interpreting the underlying bytes as int types, which could lead to the numbers you're seeing. I'm surprised you're not running into segmentation faults as this would cause you to overstep the block of the memory pointed to by the original char *.

Related

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.

returning an int array

I have created the following program which is supposed to return an int array to the main function, which will then display it on the screen.
#include <iostream.h>
int* returnArray(){
int* arr;
arr[0]=1;
arr[1]=2;
arr[2]=3;
return arr;
}
int main(){
int* res = returnArray();
for(int i=0; i<3; i++){
cout<<res[i]<<" ";
}
return 0;
}
And i was expecting it to print
1 2 3
but instead, it prints 3 someNumberWhichLooksLikeAPointer 0
Why is that? what can i do to return an int array from my function? Thank you very much!
You forgot to allocate your array:
int* arr = new int[3];
You also need to return it, and free the memory inside main after you finish with the loop in order to avoid a memory leak:
delete[] res;
Although this approach works, it is not ideal. If you have an option of returning a container, say, std::vector<int> it would be a much better choice.
If you must stay with plain arrays, another solution for filling an array inside an API is to pass it in, along with its size:
void fillArray(int *arr, size_t s){
if (s > 0) arr[0]=1;
if (s > 1) arr[1]=2;
if (s > 2) arr[2]=3;
}
int main(){
int res[3];
fillArray(res, 3);
for(int i=0; i<3; i++){
cout<<res[i]<<" ";
}
return 0;
}
You have tagged the question with C++. You Yous should consider to use the C++ solution: use a vector of int
#include <iostream>
#include <vector>
std::vector<int> returnArray(){
std::vector<int> arr(3);
arr[0]=1;
arr[1]=2;
arr[2]=3;
return arr;
}
int main(){
std::vector<int> res = returnArray();
for(int i=0; i<3; i++){
std::cout<<res[i]<<" ";
}
return 0;
}

Return an array of compared char pointers in C++ [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 8 years ago.
I'm at college and we're learning pointers. Our job was to input a char, compare it to an array and return a pointer to the first reference of that char in the array. But, as I don't like easy things, I've asked my teacher what about having that char more than once in the array.
That's where my headache begins.
So I have this code. The idea is: create a function that compares the input char to the entire array, get the pointers of the references and save them in an array and return that array.
Unfortunately it's not working as I wish :(
What can be wrong?
#include<iostream>
#include<cstdlib>
using namespace std;
char list [10];
int main()
{
initialize();
show();
cout<<search('1');
}
void initialize()
{
int i;
for(i=0; i<10;i++)
{
list[i]='1';
}
}
void show()
{
int i;
for(i=0; i<10;i++)
{
cout<<list[i];
}
}
int* search(char* input)
{
int* result[10];
int i;
char *temp;
for (i=0; i<10; i++)
{
*temp=list[i];
if(strcmp(temp, input) != NULL)
{
result[i]=i;
}
}
return result[];
}
I'm on a mobile device so I can't go into huge detail unfortunately, but you are returning a pointer to an array that you create in the function which goes out of scope at the end of the function.
My massive edit:
As everyone has already stated, a C++ array is actually only a pointer to the first element in the array. As a result, if you return a pointer to an array created in the scope of the function, you are returning a pointer to garbage. If I were doing this I would use a vector, but if I were to be forced into using an array, I would use something like the code below. Hope this helps!
#include <iostream>
#include <cstdlib>
void initialize(char* list) {
for(int i = 0; i < 10; ++i) {
if(i < 4) {
list[i] = '2';
} else {
list[i] = '1';
}
}
}
void show(char *list) {
for(int i = 0; i < 10; ++i) {
std::cout << list[i] << ' ';
}
std::cout << std::endl;
}
// Note the function requires an additional argument that is a pointer
// this is how you can avoid returning a pointer
int search(char input, char* list, char* result) {
int j = 0;
for(int i = 0; i < 10; ++i) {
// comparing characters can be done via ==
if(input == list[i]) {
*(result + j) = list[i];
// You could use result[j], but I used this to show that
// result really is just a pointer to the first element
// of the array. As a result saying result[j] is the same
// as saying I want to deference j elements past the first
// element or *(result + j)
++j; // increment j
}
}
// return how many elements matched
return(j);
}
int main(int argc, char *argv[]) {
char list[10];
char temp[10];
initialize(list);
show(list);
int size = search('1', list, temp);
// create a dynamically sized array containing space for each match
// because we don't know the size at compile time we must use
// a library type or a dynamically sized array
char *result = new char[size];
for(int i = 0; i < size; ++i) {
result[i] = temp[i];
// again you could use result[i]
std::cout << *(result + i) << std::endl;
}
delete[] result; // otherwise you'll get a memory leak
return(0);
}

How to make a multidimensional array from a normal array in c++

If i had an array of lets say 15 elements is there anyway for me to make it into a 2d array having it 5x3?
Or if i had a string with 15 letters would it be possible to make it into a 2d array having it 5x3?
This is what i have(using variables but using 5 as a and 3 as b in console)
void finishMap(string map, int a, int b)
{
string finalMap[a][b];
for(int i = 0; b>i; i++)
{
for(int x = 0; a>x; x++)
{
finalMap[a][b] += {{map[x]}, {i}};
}
}
}
Also pretty new to c++ so if you see anything i shouldn't be please tell me :3
I'm using char arrays (c strings) in my answer because I think they are useful to illustrate how arrays work - and thre really isn't a point in using std::string in your case. std::string hides a lot of the underlying nuts and bolts so I would generally recommend to play around with C strings first to understand how std::string works. Also, check out this tutorial: http://www.cplusplus.com/doc/tutorial/arrays/
A 2-dimensional array has the same memory layout as a 1-d array. In terms of memory layout, char[3][5] is the same as char[3*5] is the same as char[15]. You can use a 1-d array as a 2-d array using char[column+row*width]. The only difference if you use subscripts is that the compiler remembers how many dimensions there are and will do the whole column+row*width calculation for you.
Take this example:
char temp[5] = "abcd"; //need 5 for string termination char `\0`
for(int i = 0; i < 4; ++i) {
std::cout << temp[i];
}
std::cout << "\n\n";
for(int i = 0; i < 2; ++i) {
for(int j = 0; j < 2; ++j) {
std::cout << temp[j+2*i];
}
std::cout << std::endl;
}
Will print:
abcd
ab
cd
You can always access an array in strides. Here's a possible example using templates to restride a 1D array as a 2D array:
template <typename T, unsigned int N1, unsigned int N2>
struct strider
{
using array_type = T[N1 * N2];
array_type & data_;
Strider(array_type & data) : data_(data) {}
T & operator()(std::size_t i1, std::size_t i2)
{
return data_[i1 * N2 + i2];
}
};
template <unsigned int N1, unsigned int N2, T>
strider<T, N1, N2> stride(T (&a)[N1, N2]) { return {a}; }
Usage:
int a[15] = {};
strider<int, 3, 5> s(a);
s(1, 2) = 20;
assert(a[7] == 20);
stride<5, 3>(a)(4, 2) = 10;
assert(a[14] == 10);
I've overloaded operator() for the strided access, since unlike operator[] it can have arbirary signatures.
With some more work you could make the rank of the strided view variadic.
Okey so i used something a bit different then what i mentioned. What i did was have the user enter 3 lines of 5 length letters, which i figured out how to add into the 2d array. If your having the same issue as me, heres my code:
int main()
{
string path;
int a, b;
cin >> a >> b;
string finalMap[a][b];
for(int i = 0; b>i; i++){
cin >> path;
for(int x = 0; a>x; x++){
finalMap[x][i] = (path[x]);
}
}
for(int x = 0; b>x; x++)
{
for(int y = 0; a>y; y++)
{
cout << finalMap[y][x];
}
cout << endl;
}
return 0;
}
Thanks for trying tho, really appreciate it ^.-
You can try to use reinterpret_cast. Complete example:
#include <iostream>
using namespace std;
typedef char mtrx[5][3];
int main(){
char data[15] = "Some String";
mtrx &m = *reinterpret_cast<mtrx*>(&data);
m[1][2] = '*';
cout << data << endl;
return 0;
}

c++ array to vector issue

Im trying to copy an array to a vector, however, when the data is copied to the vector its different from that of the original array.
int arraySize = 640000;
std::vector<unsigned char> vector_buffer;
unsigned char buffer[arraySize];
populateArray(&buffer);
for(int i = 0; i < arraySize; i++)
cout << buffer[i]; // this prints out data
std::copy ( buffer, buffer + arraySize, std::back_inserter(vector_buffer));
for(int i = 0; i < arraySize; i++)
cout << vector_buffer[i]; // this prints out different data
The data seems to get compressed somehow. Any approach at copying the array to a vector does the same thing.
Im using it to create a video from images. If i use the array data all is well, but if i use the vector data it doesn't work.
Any help would be highly appreciated.
Cheers
The
int arraySize = 640000;
needs to be const in standard C++. g++ allows variable length arrays as a C99-inspired language extension. It's best to turn that extension off. :-)
std::vector<unsigned char> vector_buffer;
unsigned char buffer[arraySize];
OK when arraySize is const, but will not compile with e.g. Visual C++ with your original code.
populateArray(&buffer);
This should most probably be populateArray(buffer), unless you have a really weird declaration of populateArray.
for(int i = 0; i < arraySize; i++)
cout << buffer[i]; // this prints out data
The above prints the data with no spacing between the elements. Better add some spacing. Or newlines.
std::copy ( buffer, buffer + arraySize, std::back_inserter(vector_buffer));
Better just use the assign method of std:.vector, like vector_buffer.assign( buffer, buffer + arraySize ).
for(int i = 0; i < arraySize; i++)
cout << vector_buffer[i]; // this prints out different data
Again, this displays the elements with no spacing between.
Is the apparent problem there still when you have fixed these things?
If so, then please post also your populateArray function.
I can see nothing wrong with your code. The following code
#include <iostream>
#include <vector>
int main()
{
const std::size_t arraySize = 640000;
unsigned char buffer[arraySize];
for(std::size_t idx = 0; idx < arraySize; ++idx)
buffer[idx] = idx;
std::vector<unsigned char> vector_buffer(buffer, buffer + arraySize);
//std::vector<unsigned char> vector_buffer;
//std::copy (buffer, buffer + arraySize, std::back_inserter(vector_buffer));
for(std::size_t idx = 0; idx < arraySize; ++idx)
if( buffer[idx] != vector_buffer[idx] )
{
std::cout << "error #" << idx << '\n';
return 1;
}
std::cout << "Ok.\n";
return 0;
}
prints Ok. for me. (Even if I use the less-than-optimal way of copying into the vector.)
From the fact that the code you showed wouldn't compile I conclude that you're not showing the real code. Please do so. Somewhere in the differences between your real code and my code must be the problem.
I've written a complete compilable program for you. The code appears fine. I run it and get expected output. Perhaps you need to re-check the code you posted against the real code.
#include <cstdlib>
#include <vector>
#include <iostream>
#include <iterator>
using namespace std;
void populateArray(unsigned char* buf, size_t buf_size)
{
unsigned char* buf_end = &buf[buf_size];
for( unsigned char c = 'A'; buf != buf_end; c = (c=='Z'?'A':c+1), ++buf )
*buf = c;
}
int main()
{
static const int arraySize = 64;
std::vector<unsigned char> vector_buffer;
unsigned char buffer[arraySize];
populateArray(buffer, sizeof(buffer));
for(int i = 0; i < arraySize; i++)
cout << buffer[i]; // this prints out data
cout << endl;
std::copy ( buffer, buffer + arraySize, std::back_inserter(vector_buffer));
for(int i = 0; i < arraySize; i++)
cout << vector_buffer[i]; // this prints out different data
return 0;
}