Pointer to int array, passing and using it from another method - c++

I haven't cemented my learning of C++ arrays and have forgotten how to do this properly. I've done it with char array before but its not working as well for int array.
I declare a new blank int array:
int myIntArray[10];
So this should be an array of nulls for the moment correct?
Then I assign a pointer to this array:
int *pMyArray = myIntArray
Hopefully thats correct to there.
Then I pass this to another method elsewhere:
anotherMethod(pMyArray)
where I want to assign this pointer to a local variable (this is where I'm really not sure):
anotherMethod(int *pMyArray){
int myLocalArray[];
myLocalArray[0] = *pMyArray;
}
I'm not getting any compilation errors but I'm not sure this is right on a few fronts. Any and all help and advice appreciated with this.
Edit:
I should have said what I am trying to do.
Very simple really, I'd just like to modify a local array from another method.
So I have:
Method 1 would contain:
int myArray1[10] = {0};
Method 2 would be passed the pointer to myArray:
Then some code to modify the variables in the array myArray.

int myIntArray[10];
This is an uninitialized array. It doesn't necessarily contain 0's.
int *pMyArray = myIntArray
Okay, pMyArray points to the first element in myIntArray.
anotherMethod(int *pMyArray){
int myLocalArray[10];
myLocalArray[0] = *pMyArray;
}
This doesn't assign your pointer to anything, it assigns the first value of the local array to the int pointed to by pMyArray, which, remember, was uninitialized. I added the 10 there because you can't have an array of unknown size in C++.
To modify what pMyArray points to, you need to pass it by reference:
anotherMethod(int *& pMyArray)
Also, if you assign it to some values in automatic storage, it will result in undefined behavior, as that memory is no longer valid when the function exits.

int myIntArray[10];
So this should be an array of nulls for the moment correct?
No, this is an array of 10 integers containing values depending on the storage specification.
If created locally, it has random garbage values.
If created globally it is value initialized which is zero initialized for POD.
Besides that your method just assigns the local array with the first vale of the array you pass.
What are you trying to do exactly? I am not sure.

int myIntArray[10];
So this should be an array of nulls for the moment correct?
Not correct, it is an array of 10 uninitialized ints.
int *pMyArray = myIntArray
Hopefully thats correct to there.
Not quite correct, pMyArray is a pointer to the 1st element, myIntArray[0].
where I want to assign this pointer to a local variable (this is where
I'm really not sure):
If you really need to assign the pointer, you have to use this code
int *p_myLocalArray;
p_myLocalArray = pMyArray;

There are a few mistakes here.
First, array of zeros (not nulls) is achieved by using the initializer syntax:
int myIntArray[10] = {0};
Second, int myLocalArray[]; has a size of 0. And even if it did have a size of, say, 10, writing myLocalArray[0] = *pMyArray; will assign the first int from pMyArray into mLocalArray, which is not what you meant.
If you want to assign a pointer of the array, then simply:
int *myLocalPointer;
myLocalPointer = pMyArray;
If you want a local copy of the array, you will need to copy it locally, and for that you also need the size and dynamic allocation:
void anotherMethod(int *pMyArray, int size){
int *myLocalArray = (int *)malloc(size * sizeof(int));
memcpy(myLocalArray, pMyArray, size * sizeof(int));
...
free(myLocalArray);
}

Related

variable-sized object may not be initialized c++

I understand that this question was asked before but I don't get why it doesn't work in my case
void calc(vector<char> zodis1, vector<char> zodis2, vector<char> zodisAts,int zo1,int zo2,int zoA)
{
int i,u=0;
int zod1[zo1]=0;
int zod2[zo2]=0;
int zodA[zoA]=0;
}
All 3 of zod1, zod2, zoA gives me error: variable-sized object may not be initialized c++
But compiler should know the meaning of zo before initialization cause cout<<zo1; works and print out the meaning
So whats the problem?
You can declare an array only with constant size, which can be deduced at compile time. zo1,zo2 and zoA are variables, and the values can be known only at runtime.
To elaborate, when you allocate memory on the stack, the size must be known at compile time. Since the arrays are local to the method, they will be placed on the stack. You can either use constant value, or allocate memory in the heap using new, and deallocate when done using delete, like
int* zod1 = new int[zo1];
//.... other code
delete[] zod1;
But you can use vector instead of array here also, and vector will take care of allocation on the heap.
As a side note, you should not pass vector by value, as the whole vector will be copied and passed as argument, and no change will be visible at the caller side. Use vector<char>& zodis1 instead.
Here is the fix, you can write the following lines instead of the line where you got the error;
Alternative 1 you can use vectors:
vector<int> zod1(zo1, 0);
Alternative 2 (for example, since w know "0 <= s.length <= 100", we can use constant value):
int zod1[100] = { 0 };

why does this fail

i am stuck and unable to figure out why this is the following piece of code is not running .I am fairly new to c/c++.
#include <iostream>
int main(){
const char *arr="Hello";
const char * arr1="World";
char **arr2=NULL;
arr2[0]=arr;
arr2[1]=arr1;
for (int i=0;i<=1;i++){
std::cout<<arr2[i]<<std::endl;
}
return 0;
}
where as this is running perfectly fine
#include <iostream>
int main(){
const char *arr="Hello";
const char * arr1="World";
char *arr2[1];
arr2[0]=arr;
arr2[1]=arr1;
for (int i=0;i<=1;i++){
std::cout<<arr2[i]<<std::endl;
}
return 0;
}
Why is this? and generally how to iterate over a char **?
Thank You
char *arr2[1]; is an array with one element (allocated on the stack) of type "pointer to char". arr2[0] is the first element in that array. arr2[1] is undefined.
char **arr2=NULL; is a pointer to "pointer to char". Note that no memory is allocated on the stack. arr2[0] is undefined.
Bottom line, neither of your versions is correct. That the second variant is "running perfectly fine" is just a reminder that buggy code can appear to run correctly, until negligent programming really bites you later on and makes you waste hours and days in debugging because you trashed the stack.
Edit: Further "offenses" in the code:
String literals are of type char const *, and don't you forget the const.
It is common (and recommended) practice to indent the code of a function.
It is (IMHO) good practice to add spaces in various places to increase readability (e.g. post (, pre ), pre and post binary operators, post ; in the for statement etc.). Tastes differ, and there is a vocal faction that actually encourages leaving out spaces wherever possible, but you didn't even do that consistently - and consistency is universially recommended. Try code reformatters like astyle and see what they can do for readability.
This is not correct because arr2 does not point to anything:
char **arr2=NULL;
arr2[0]=arr;
arr2[1]=arr1;
correct way:
char *arr2[2] = { NULL };
arr2[0]=arr;
arr2[1]=arr1;
This is also wrong, arr2 has size 1:
char *arr2[1];
arr2[0]=arr;
arr2[1]=arr1;
correct way is the same:
char *arr2[2] = { NULL };
arr2[0]=arr;
arr2[1]=arr1;
char **arr2=NULL;
Is a pointer to a pointer that points to NULL while
char *arr2[1];
is an array of pointers with already allocated space for two items.
In the second case of the pointer to a pointer you are are trying to write data in a memory location that does not exist while in the first place the compiler has already allocated two slots of memory for the array so you can assign values to the two elements.
If you think of it very simplistically, a C pointer is nothing but an integer variable, whose value is actually a memory address. So by defining char *x = NULL you are actually defining a integer variable with value NULL (i.e zero). Now suppose you write something like *x = 5; This means go to the memory address that is stored inside x (NULL) and write 5 in it. Since there is no memory slot with address 0, the the entire statement fails.
To be honest it;s been ages since I last had to deal with such stuff however this little tutorial here, might clear the motions of array and pointers in C++.
Put simply the declaration of a pointer does NOT reserve any memory, where as the declration of a array doesn't.
In your first example
Your line char **arr2=NULL declares a pointer to a pointer of characters but does not set it to any value - thus it is initiated pointing to the zero byte (NULL==0). When you say arr2[0]=something you are attempting to place a valuei nthis zero location which does not belong to you - thus the crash.
In your second example:
The declaration *arr2[2] does reserve space for two pointers and thus it works.

Can't set variable length with variable

What I'm trying to do right now is to create an array with a length that is defined by a variable. However, when I put the variable in the array length, it gives me a "Variable length array of non-POD element type 'glm::vec2'" error. However, if I replace the variable with an actual number, the error goes away. Why does this happen and how can I fix this?
int numtriangles = sector1.numtriangles;
glm::vec2 tex[test]; //Using a variable generates an error
glm::vec3 vertices[10]; //No error here
You cannot have variable length arrays(VLA) in standard C++.
Variable length arrays are not allowed by the C++ Standard. In C++ the length of the array needs to be a compile time constant. Some compilers do support VLA as a compiler extension, but using them makes your code non-portable across other compilers.
You can use, std::vector instead of an VLA.
See this question Is there a way to initialize an array with non-constant variables? (C++)
Short answer is no you cannot directly do this. However you can get the same effect with something like
int arraySize = 10;
int * myArray = new int[arraySize];
Now myArray is a pointer to the array and you can access it like an array like myArray[0], etc.
You can also use a vector which will allow you to have a variable length array. My example allows you to create an array with a variable initailizer however myArray will be only 10 items long in my example. If you aren't sure how long the array will ever be use a vector and you can push and pop items off it.
Also keep in mind with my example that since you've dyanmically allocated memory you will need to free that memory when you are done with the array by doing something like
delete[] myArray;
Here is a little sample app to illustrate the point
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int arraySize = 10;
int * myArray = new int[arraySize];
myArray[0] = 1;
cout << myArray[0] << endl;
delete[] myArray;
}
use STL.
IF you want a variable length array you can use vectors under #include<vector>
Native c++ array donot nave variable length array.
When you declare an array with a length specifier, only constants are allowed.
Actually it's when the program is compiled that the array length is evaluated.
Note however that it's illegal in C++ to declare int test[]; like the compiler has no way to know how much space to allocate for the variable.
Without a length specifier, there is no actual memory that is reserved for the array, and you have to resort to using pointers and dynamic memory allocation:
int * test = new int[12];
// or
int * test = new int[val]; // variable works here
// and don't forget to free it
delete [] test;
Using int test[12] actually creates an array that is statically initialized once and for all to contain 12 integers at compile time.
Do not ever attempt to do delete [] test with a variable declared this way, as it's most certainly going to make your program crash.
To be precise, if the array is declared in a function, it will use space on the program stack, and if declared in a global context, program data memory will be used.
C++ doesn't support declare variable length array. So to use a array with a length you may
Assume
a big number which is highest possible length of your array. Now declare an array of that size. And use it by assuming that it an array of your desire length.
#define MAX_LENGTH 1000000000
glm::vec2 tex[MAX_LENGTH];
to iterate it
for(i=0; i<test; i++) {
tex[i];
}
Note: memory use will not minimized in this method.
Use pointer and allocate it according your length.
glm::vec2 *tex;
tex = new glm::vec2[test];
enter code here
for(i=0; i<test; i++) {
tex[i];
}
delete [] tex; // deallocation
Note: deallocation of memory twice will occur a error.
Use other data structure which behave like array.
vector<glm::vec2> tex;
for(i=0; i<test; i++){
tex.push_back(input_item);
}
/* test.size() return the current length */

Pass character array by value and return a new character array from the function?

I apologise if I'm completely misunderstanding C++ at the moment, so my question might be quite simple to solve. I'm trying to pass a character array into a function by value, create a new array of the same size and fill it with certain elements, and return that array from the function. This is the code I have so far:
char *breedMutation(char genome []){
size_t genes = sizeof(genome);
char * mutation = new char[genes];
for (size_t a = 0 ;a < genes; a++) {
mutation[a] = 'b';
}
return mutation;
}
The for loop is what updates the new array; right now, it's just dummy code, but hopefully the idea of the function is clear. When I call this function in main, however, I get an error of initializer fails to determine size of ‘mutation’. This is the code I have in main:
int main()
{
char target [] = "Das weisse leid"; //dummy message
char mutation [] = breedMutation(target);
return 0;
}
I need to learn more about pointers and character arrays, which I realise, but I'm trying to learn by example as well.
EDIT: This code, which I'm trying to modify for character arrays, is the basis for breedMutation.
int *f(size_t s){
int *ret=new int[s];
for (size_t a=0;a<s;a++)
ret[a]=a;
return ret;
}
Your error is because you can't declare mutation as a char[] and assign it the value of the char* being returned by breedMutation. If you want to do that, mutation should be declared as a char* and then deleted once you're done with it to avoid memory leaks in a real application.
Your breedMutation function, apart from dynamically allocating an array and returning it, is nothing like f. f simply creates an array of size s and fills each index in the array incrementally starting at 0. breedMutation would just fill the array with 'b' if you didn't have a logic error.
That error is that sizeof(genome); will return the size of a char*, which is generally 4 or 8 bytes on a common machine. You'll need to pass the size in as f does since arrays are demoted to pointers when passed to a function. However, with that snippet I don't see why you'd need to pass a char genome[] at all.
Also, in C++ you're better off using a container such as an std::vector or even std::array as opposed to dynamically allocated arrays (ones where you use new to create them) so that you don't have to worry about freeing them or keeping track of their size. In this case, std::string would be a good idea since it looks like you're trying to work with strings.
If you explain what exactly you're trying to do it might help us tell you how to go about your problem.
The line:
size_t genes = sizeof(genome);
will return the sizeof(char*) and not the number of elements in the genome array. You will need to pass the number of elements to the breedMutation() function:
breedMutation(target, strlen(target));
or find some other way of providing that information to the function.
Hope that helps.
EDIT: assuming it is the number of the elements in genome that you actually want.
Array are very limited.
Prefer to use std::vector (or std::string)
std::string breedMutation(std::string const& genome)
{
std::string mutation;
return mutation;
}
int main()
{
std::string target = "Das weisse leid"; //dummy message
std::string mutation = breedMutation(target);
}
Try replacing the second line of main() with:
char* mutation = breedMutation(target);
Also, don't forget to delete your mutation variable at the end.

C++ Why is this passed-by-reference array generating a runtime error?

void pushSynonyms (string synline, char matrizSinonimos [1024][1024]){
stringstream synstream(synline);
vector<int> synsAux;
int num;
while (synstream >> num) {synsAux.push_back(num);}
int index=0;
while (index<(synsAux.size()-1)){
int primerSinonimo=synsAux[index];
int segundoSinonimo=synsAux[++index];
matrizSinonimos[primerSinonimo][segundoSinonimo]='S';
matrizSinonimos [segundoSinonimo][primerSinonimo]='S';
}
}
and the call..
char matrizSinonimos[1024][1024];
pushSynonyms("1 7", matrizSinonimos)
It's important for me to pass matrizSinonimos by reference.
Edit: took away the & from &matrizSinonimos.
Edit: the runtime error is:
An unhandled win32 exception occurred in program.exe [2488]![alt text][1]
What's wrong with it
The code as you have it there - i can't find a bug. The only problem i spot is that if you provide no number at all, then this part will cause harm:
(synsAux.size()-1)
It will subtract one from 0u . That will wrap around, because size() returns an unsigned integer type. You will end up with a very big value, somewhere around 2^16 or 2^32. You should change the whole while condition to
while ((index+1) < synsAux.size())
You can try looking for a bug around the call side. Often it happens there is a buffer overflow or heap corruption somewhere before that, and the program crashes at a later point in the program as a result of that.
The argument and parameter stuff in it
Concerning the array and how it's passed, i think you do it alright. Although, you still pass the array by value. Maybe you already know it, but i will repeat it. You really pass a pointer to the first element of this array:
char matrizSinonimos[1024][1024];
A 2d array really is an array of arrays. The first lement of that array is an array, and a pointer to it is a pointer to an array. In that case, it is
char (*)[1024]
Even though in the parameter list you said that you accept an array of arrays, the compiler, as always, adjusts that and make it a pointer to the first element of such an array. So in reality, your function has the prototype, after the adjustments of the argument types by the compiler are done:
void pushSynonyms (string synline, char (*matrizSinonimos)[1024]);
Although often suggested, You cannot pass that array as a char**, because the called function needs the size of the inner dimension, to correctly address sub-dimensions at the right offsets. Working with a char** in the called function, and then writing something like matrizSinonimos[0][1], it will try to interpret the first sizeof(char**) characters of that array as a pointer, and will try to dereference a random memory location, then doing that a second time, if it didn't crash in between. Don't do that. It's also not relevant which size you had written in the outer dimension of that array. It rationalized away. Now, it's not really important to pass the array by reference. But if you want to, you have to change the whole thingn to
void pushSynonyms (string synline, char (&matrizSinonimos)[1024][1024]);
Passing by reference does not pass a pointer to the first element: All sizes of all dimensions are preserved, and the array object itself, rather than a value, is passed.
Arrays are passed as pointers - there's no need to do a pass-by-reference to them. If you declare your function to be:
void pushSynonyms(string synline, char matrizSinonimos[][1024]);
Your changes to the array will persist - arrays are never passed by value.
The exception is probably 0xC00000FD, or a stack overflow!
The problem is that you are creating a 1 MB array on the stack, which probably is too big.
try declaring it as:
void pushSynonyms (const string & synline, char *matrizSinonimos[1024] )
I believe that will do what you want to do. The way you have it, as others have said, creates a 1MB array on the stack. Also, changing synline from string to const string & eliminates pushing a full string copy onto the stack.
Also, I'd use some sort of class to encapsulate matrizSinonimos. Something like:
class ms
{
char m_martix[1024][1024];
public:
pushSynonyms( const string & synline );
}
then you don't have to pass it at all.
I'm at a loss for what's wrong with the code above, but if you can't get the array syntax to work, you can always do this:
void pushSynonyms (string synline, char *matrizSinonimos, int rowsize, int colsize )
{
// the code below is equivalent to
// char c = matrizSinonimos[a][b];
char c = matrizSinonimos( a*rowsize + b );
// you could also Assert( a < rowsize && b < colsize );
}
pushSynonyms( "1 7", matrizSinonimos, 1024, 1024 );
You could also replace rowsize and colsize with a #define SYNONYM_ARRAY_DIMENSION 1024 if it's known at compile time, which will make the multiplication step faster.
(edit 1) I forgot to answer your actual question. Well: after you've corrected the code to pass the array in the correct way (no incorrect indirection anymore), it seems most probable to me that you did not check you inputs correctly. You read from a stream, save it into a vector, but you never checked whether all the numbers you get there are actually in the correct range. (end edit 1)
First:
Using raw arrays may not be what you actually want. There are std::vector, or boost::array. The latter one is compile-time fixed-size array like a raw-array, but provides the C++ collection type-defs and methods, which is practical for generic (read: templatized) code.
And, using those classes there may be less confusion about type-safety, pass by reference, by value, or passing a pointer.
Second:
Arrays are passed as pointers, the pointer itself is passed by value.
Third:
You should allocate such big objects on the heap. The overhead of the heap-allocation is in such a case insignificant, and it will reduce the chance of running out of stack-space.
Fourth:
void someFunction(int array[10][10]);
really is:
(edit 2) Thanks to the comments:
void someFunction(int** array);
void someFunction(int (*array)[10]);
Hopefully I didn't screw up elsewhere....
(end edit 2)
The type-information to be a 10x10 array is lost. To get what you've probably meant, you need to write:
void someFunction(int (&array)[10][10]);
This way the compiler can check that on the caller side the array is actually a 10x10 array. You can then call the function like this:
int main() {
int array[10][10] = { 0 };
someFunction(array);
return 0;
}