array size and const [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
initialize array size from another array value
in C++
const int a[]={1,2,3,4,5};
int b[a[2]];
int main()
{
return 0;
}
The code is giving error in line 2;
However, if it is something like below it gives no error after compilation:
const int a=3;
int b[a];
int main()
{
return 0;
}
Why is that? however if i define array b inside main it is alright in both the cases...

Because in C++ array sizes must be constant expressions, not just constant data. Array data, even though const, is not a constant expression.
Second version IS a constant expression.

It looks like you want to make a variable-sized array. To do this, one must use pointers.
POINTERS
Normally, you would declare an array like this:
char a[4];
An array must be a constant size. It cannot change. How can we make the size variable? Like this.
char* a = new char[length];
What does this do? Normally, when you declare an array of a specific size, it is declared on the stack. What this code does, however, is instead allocate memory on the heap.
char a[4]; // This is created at compile time
char* a = new char[length]; // This is created at run time
You create a pointer to an address where you can declare and assign values to your array, all in a safe memory space.

Related

Is it safe to extend memory like following [duplicate]

This question already has answers here:
How do you 'realloc' in C++?
(4 answers)
Closed 2 years ago.
I have made a code in which i am creating array of objects using new.I am extending the array by another new keyword and last index of previous array like following.Its working fine(The constructor is printing "a" number of times the net index). But i dont know is it safe or not? My main motive is to make a dynamic array but i cant use malloc because it dows not call constructors.So i am using new. But idont know how to reallocate memory after using new. If i use realloc then the program is not giving any error but realloc is not calling the constructor.
Summary:->Just want to call constructor while reallocating memory.
I have given the image of my code
class xy
{
unsigned x[10],y[10],counter;
public:
xy()
{counter=0;}
void setxy(unsigned a,unsigned b)
{x[counter]=a;y[counter]=b;counter++;}
void printxy()
{for(unsigned i=0;i<counter;i++)cout<<"="<<x[i]<<"^3+"<<y[i]<<"^3";}
};
class unitcell
{
unsigned long long value_cube,hasharr_len;
xy* hasharr;
unsigned long long* r_numberindexes;
unsigned rarraylen;
public:
unitcell()
{cout<<"a";}
unsigned long long gethasharraylen()
{return hasharr_len;}
};
int main()
{
unitcell *a=new unitcell[3];
unitcell *b=a+3;
b=new unitcell[3];
}
No.
First you're initializing b to the value of a+3 and then you're assigning the result of new to it, which will be a completely different value. You have no control over where your allocated memory will end up. You should assume each new invocation gives you a completely random address, whose value you cannot predict.
If you want to "extend" your array you have to allocate a bigger one, copy all the elements you already had and then delete the old one
unitcell *b = new unitcell[6];
std::copy(a, a+3, b);
delete a;
a = b;
STL class std::vector works in this way internally.

C++ Returning an Array and Assigning It to a Variable [duplicate]

This question already has answers here:
How do I use arrays in C++?
(5 answers)
Closed 8 years ago.
So I have a homework problem that asks that I write a function that takes an array of chars, a char, and an int pointer. The function should loop through the array of chars, ignore any instance of the second parameter char, and create a new array which is composed of the characters in the original array other than instances of the second parameter char. Then the original length parameter needs to be changed to the new length, and the new array should be returned. I'm very new to C++ so pointers are a new concept which I haven't fully grasped yet.
char *Problem5(char chars[], char letter, int *length){
int newLength=0;
int counter=0;
for(int i=0;i<*length;i++){
if(chars[i]!=letter){
newLength++;
}
}
char newChars[newLength];
for(int x=0;x<*length;x++){
if(chars[x]!=letter){
newChars[counter]=chars[x];
counter++;
}
}
*length=newLength;
return newChars;
}
There is my function, I know the algorithm works fine but it won't compile.
char chars2[10] = {'g','g','c','g','a','g','g','g','t','g'};
printArray(chars2,10);
char *arrayPointer;
arrayPointer = Problem5(chars2,'g',length1);
printArray(arrayPointer,3);
And this is the section of my main function where it is called. I need to print out the resultant array, and so I try to assign it to a pointer, but this line:
arrayPointer = Problem5(chars2,'g',length1);
Throws an error: Invalid conversion from 'char' to 'char*' A little insight would be very much appreciated because I have no clue what I'm doing wrong.
Your algorithm looks ok and your code looks pretty much all right. I am a little skeptical of this line :
char newChars[newLength];
because you can't allocate an array at compile time with a variable size. Is it possible that the code you posted isn't exactly the code you tried to compile?
Change the line above to
char *newChars = new char[newLength];
and the array will be allocated dynamically at run time. I cannot understand why you would get an "Invalid conversion from 'char' to 'char*'" error compiling
arrayPointer = Problem5(chars2,'g',length1);
given the definitions that you've provided. The only things that have type "char*" are the first parameter to and return value from Problem5, and those look to be the correct types from what you've posted.

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

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);
}

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 */

Returning integer array from function with no arguments [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Returning local data from functions in C and C++ via pointer
I need to create a function with no arguments that returns an array
I get the error: "warning: function returns address of local variable"
my code has been simplified for ease of reading
int * getNums()
{
int nums[8];
nums = {1,2,3,4,5,6,7,8};
return nums;
}
I am led understand that when the function ends the pointer is lost, but will the array still be sent? If not, what is a good way to return this integer array with no arguments in the function call?
Appreciate the help in advance!
Cheers
No, the array will not be "sent". You need to do one of these:
create the array dynamically using new
create the array statically
pass the array into the function as a pointer
use std::vector
In most cases, the last is the preferred solution.
Pretend you don't know what C-arrays are and join the world of modern C++:
#include <array>
std::array<int, 8> getNums()
{
std::array<int, 8> ret = {{ 1, 2, 3, 4, 5, 6, 7, 8 }};
return ret;
}
If your compiler is too old to provide a std:: or std::tr1:: implementation of array<>, consider using boost::array<> instead. Or, consider using std::vector<> either way.
I am led understand that when the function ends the pointer is lost, but will the array still be sent?
The behavior is undefined.
what is a good way to return this integer array with no arguments in the function call?
int nums[8];
num is local variable which resides on stack. You cannot return the reference of a local variable. Instead alloc nums with operator new and remember to delete[] it.
int* getNums()
{
int *nums = new int[8] ;
// .....
return nums ;
}
// You should deallocate the resources nums acquired through delete[] later,
// else memory leak prevails.
Whenever a function exits all the local variables created within that function get trashed.
You are creating an array local to the function and then returning a pointer to the array. The returned pointer will point to an memory location which is already reclaimed by the OS. So it wont work for you.
Instead of Arrays, You should use vectors, since it is C++
You can't return a simple array in C++. Try
int *getNums()
{
int *nums = new int[8];
...
return nums;
}
Now nums is a pointer to a heap array which will live on after getNums returns.
int* getNums()
{
static int nums[8];
nums = {1,2,3,4,5,6,7,8};
return nums;
}
It should propabally work now :)
Your array is a regular stack-based local variable. That means that it disappears when you return from the function and returning a pointer to it does not work. You have to make the array live longer, which can be done by turning it into a static variable or allocating it on the heap:
int *getArray {
static int foo[] = {…};
return foo;
}
int *getArray {
int foo[] = calloc(numberOfItems, sizeof(int));
foo = …;
return foo;
}
Both solutions have implications that you should understand before you use one. Namely, the static allocation (first option) is mainly a curiosity nowaydays, since it creates a sort of a global variable and causes more problems than it solves. The heap-allocated array is quite common, but it’s more customary to pass the pointer to fill using an argument to make the interface more explicit. In every case the caller is responsible for freeing the allocated memory later.
And, as others note, there are even better solutions specific to C++, if you don’t insist on using a plain C array.