How to create a variable size char array in VC++ - c++

const int sizea = 600;
char sz[sizea];
above code works fine. But below code segment cause errors.
I'm working on visual studio 2005 - MFC application
CString strFinal;
.......//strFinal value is dynamically changing . .
const int size = strFinal.GetLength();
char sz[size];
Error 2 error C2057: expected constant expression
Error 5 error C2070: 'char []': illegal sizeof operand
Error 4 error C2133: 'sz' : unknown size Error 3 error C2466: cannot allocate an array of
constant size 0

In the current version of C++, arrays must have a fixed size, specified by a compile-time constant. If you need to use a run-time value, then your options are:
most portably, use a dynamic array class such as std::string or std::vector<char>;
use a compiler that supports C99 variable-length arrays as a non-standard extension;
wait a year for dynamic arrays to (hopefully) be introduced in C++14 (and perhaps wait a bit longer for your compiler vendor to catch up).

Normal use-case is to use new (and delete when you're done) for variable-sized elements. If you must use the stack, you can use alloca.
char *psz = new char[size+1]; // +1 you probably want zero-termination
...
delete [] psz;

you can use vector as a dynamic array. Try this.
#include <vector> // use this header
#include <iostream>
using namespace std; // use this namespace
int main()
{
vector<int> v; //declare dynamic array equivalent
for (int i = 0; i < 10; ++i) {
v.push_back(10 + i);
}
cout << "vector data: " << endl;
print_collection(v);
while (v.begin() != v.end()) {
cout << "v.back(): "; print_elem(v.back()); cout << endl;
v.pop_back();
}
}

It produces an error because GetLength() returns you an arbitrary value, not statically defined.
The proper way is to allocate enough memory to hold your string and, if required, the NULL-terminated symbol either by calling malloc or by using the new operator (if compiling with C++ compiler).

I did something like this long time ago
the Idea is to work with pointers.
so you need to make structure that has (char and nextPointer)
the char represent the current value of the array and the nextPointer represent the next structure of the series
looping all through that pointers u will have your array of whatever you want your structure connected
struct yourStructure {
Char char;
double nextPointer;
} ;
so you create first structure and connect to the second and the tree

Related

How to make the array size correct in C++?

I'm trying to create an array and the size of the array depends on the user input. But there is an error in my code, It said: "expression must have a constant value".
Here is my code:
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int var;
cout << "What size do you want to choose: "<< endl;
cin >> var;
int arr[var];
}
How can I change my code and make it work?
How can I change my code and make it work?
Change
int arr[var];
to
std::vector<int> arr(var);
This will require #include <vector>
The syntax you are using is known as a "variable length array", and is NON-STANDARD. Only a few compilers support it as an vendor-specific extension to the C++ language.
A standard compliant fixed-length array must have its size known to the compiler as a compile-time constant.
For what you want, you need to use the new[] operator instead:
int *arr = new int[var];
...
delete[] arr;
Or better, use a std::vector container:
#include <vector>
std::vector<int> arr(var);
To allocate an array dynamically, we use the array form of new and delete (often called new[] and delete[]):
#include <iostream>
int main()
{
std::cout << "Enter a positive integer: ";
int length{};
std::cin >> length;
int *array{ new int[length]{} }; // use array new. Note that length does not need to be constant!
std::cout << "I just allocated an array of integers of length " << length << '\n';
array[0] = 5; // set element 0 to value 5
delete[] array; // use array delete to deallocate array
// we don't need to set array to nullptr/0 here because it's going to go out of scope immediately after this anyway
return 0;
}
Arrays in C++ must have constant size known at compile-time. You can preallocate several constant sizes known at compile time and offer the user to choose one of them. Alternatively, you can use another data structure that allows dynamic size allocation e.g std::vector.
Good luck!

How do I create a C++ Integer Array of constant length?

I am quite an experienced python programmer, attempting to learn C++. I am having an issue with initialising an integer array of a fixed size.
I have read this but creating my integer as a constant has not fixed my issue. What am i missing here?
BTW i am using VS2019 Community, any help would greatly be appreciated!
#include <iostream>
#include <sstream>
int numericStringLength(int input) {
int length = 1;
if (input > 0) {
// we count how many times it can be divided by 10:
// (how many times we can cut off the last digit until we end up with 0)
for (length = 0; input > 0; length++) {
input = input / 10;
}
}
return length;
}
int convertNumericStringtoInt(std::string numericString) {
std::stringstream data(numericString);
int convertedData = 0;
data >> convertedData;
return convertedData;
}
int main() {
std::string numericString;
std::cout << "Enter the string: ";
std::cin >> numericString;
const int length = numericStringLength(convertNumericStringtoInt(numericString));
std::cout << "Length of Numeric string: " << length << "\n";
int storage[length];
}
but creating my integer as a constant has not fixed my issue
It is not sufficient for the array length to be const. It must be compile time constant. const merely means that the object does not change throughout its lifetime - i.e. it implies runtime constness. Since length is not a compile time constant, the program is ill-formed. Examples of values that are compile time constant:
Literals such as 42
Template arguments
Enumerations
constexpr variables
const variables with compile time constant initialiser (this may have some limitations, I'm not sure)
It should be quite clear from the program that the length is calculated from user input, which would be impossible to do when the program is compiled. So since you cannot make it a compile time constant, you cannot use an array variable. You need to allocate the array dynamically. Simplest solution is to use a vector:
std::vector<int> storage(length);
Making the variable const is not enough.
const just means "I won't change this after it's initialised".
It has to be a compile-time constant, as the machinery for a basic C array is baked into the computer instructions that form your executable.
You're calculating it at runtime, so there's no way that is going to work.
You are going to have to use a vector or some other such dynamically-resizable array type.
If you want a fixed size array, you can use std::array, example:
std::array<int, 3> arr { 1,2,3 };
// ^
// fixed size needs to be known at compile time
If you don't know the size at compile time, use std::vector
The problem you have is that length is a run-time constant, whose value is calculated when the program is running. This is opposed to a compile-time constant, whose value is known by the compiler when you build your program.
Arrays needs compile-time constants for their size.
If the size is not known at compile-time but only at run-time, then you should use std::vector.

C++ Declare array of unspecified length with string elements

What I'm trying to do here is quite simple. But some way, some how I'm missing something. I'm trying to "pre-declare" an array with strictly string elements in such a way that I can update the array contents during a specific period (periodically). So here are the snippets:
string ShotBox[] = {}; //"Pre-Declare" array that could contain as many elements here
Then I have a loop within my Update container. Snippet's:
for (int i = 0; i < sizeof(ShotBox) - 1; i++){
std::string soa = sPath;
std::string so = soa + ShotBox[i];
char *cstr = new char[so.length() + 1];
strcpy(cstr, so.c_str());
scPath = cstr;
}
All is fine with everything except the fact that whichever way I try to "pre-declare", I get a memory access violation. In this very exact snippets, the exact error is: an empty array is invalid for an array with unspecified bound.
I tried using "vector" but can't seem to work around it. What's the way to solve this? Please I don't want libraries. I need direct short methods or something of such.
Use std::vector<std::string>.
The vector manages an internal array.
std::vector<std::string> ShotBox; // (empty)
ShotBox.push_back(a_string); // add a string to the internal array
std::cout << ShotBox[0] << '\n'; // print first element
The problem of memory access violation itself is caused by your misunderstanding of sizeof operator. Specifically, sizeof(ShotBox) is the size (in bytes) of your array, not the ShotBox[] array size.
for (int i = 0; i < sizeof(ShotBox)/sizeof(std::string); i++) {
...
}
Inside the for loop ShotBox[] elements aren't updated at all. The only thing that happens is concatenation of sPath with ShotBox[i] into a new C string 'cstr'. If your aim is to update ShotBox[i] element, just add the following assignment to the end of for loop:
for (int i = 0; i < N_SHOT_BOX; i++) {
...
ShotBox[i] = so;
}
It's much more convenient to use std::vector for working with collections of variable size:
#include <string>
#include <vector>
#include <memory.h>
int main() {
std::vector<std::string> ShotBox{"str1", "str2", "str3"};
for (int i = 0; i < ShotBox.size(); i++){
std::string soa = sPath;
std::string so = soa + ShotBox[i];
char *cstr = new char[so.length() + 1];
strcpy(cstr, so.c_str());
ShotBox[i] = cstr;
}
return 0;
}
Galik's answer suggesting std::vector is the Modern C++ way to do what you want to do.
The reason your code doesn't work is that the following line of code doesn't do what you think it does
string ShotBox[] = {}; //"Pre-Declare" array that could contain as many elements here
Try adding the following to your program ...
std::cout << sizeof(ShotBox) << std::endl;
... and you should find that you've declared an array that is zero bytes long. Indeed some compilers will treat an empty initializer as an error if the array bounds are not specified.
In the C++ language arrays are fixed length entities. One way to approximate a dynamic array is to use a pointer and to use memory management functions to allocate a larger array and then copy the old array contents into the new larger array.
But that is a really bad idea.
Doing it correctly with exception safety and efficiency is hard to do and if you do manage it, you'll have re-implemented std::vector which seems like wasted effort!

How to convert a vector to an array of a typdef type

I have a typedef defined in a header file as:
typedef unsigned char BYTE;
And I have the following code:
BYTE rgbPlaintext[] = {0x00};
rgbPlaintext* = &vec[0];
vec is an array of unsigned char that is populated by a file (no issue there). My issue is, the above code does not build successfully, all it says is syntax error : '=' at the line rgbPlaintext* = &vec[0];
How can I successfully point the array to the array that is in the vector that is of the underlying type of the typedef?
Thank you.
My issue is, the above code does not build successfully, all it says is syntax error : '=' at the line rgbPlaintext* = &vec[0];
You get the error because the compiler expects a right hand argument to the multiplication operator but instead found = which is not a valid operand for the multiplication operator. I get the feeling that a multiplication was not your intention.
How to convert a vector to an array of a typdef type
Vectors can not be converted to an array.
Perhaps you mean to copy the contents of the vector into an array. That's simple:
std::copy(vec.begin(), vec.end(), rgbPlaintext);
You need to be careful, however. If the array is smaller than the vector, then it will overflow and you get undefined behaviour.
How can I successfully point the array to the array that is...
Arrays do not point anything and you can not make them point anything. Arrays contain objects.
In this case the array rgbPlaintext contains a single element with the value 0x00. You can use the method I showed to copy contents of a vector to rgbPlaintext, but if the vector contains more than one element, the copy will overflow.
How would one know the size of an array needed if the vector that the array is based off of is populated by a data file?
The size of a vector can be known using std::vector::size(). But the size can not be known at compile time, so if you intend to copy the contents to an array and cannot limit the maximum size, then you cannot use an automatically or statically allocated array. You can use a dynamically allocated array, and for that, I recommend using a std::vector.
Copying a vector to another is simple:
std::vector<BYTE> rgbPlaintext = vec;
This is OK as long as BYTE is the same type as decltype(vec)::value_type. It does not matter if one type is an alias of the other.
For the code:
rgbPlaintext* = &vec[0]; // vec is an array of unsigned char
The syntax is incorrect rgbPlaintext* as said in another post.
To do the following:
How can I successfully point the array to the array that is in the vector that is of the underlying type of the typedef?
I'm going to assume that what you are really saying that vec is a vector from std that contains arrays of unsigned char's. If this is the case then I would do the following:
BYTE* rgbPlaintext = NULL;
rgbPlaintext = vec[0]; // any subscript of the list of arrays
cout << rgbPlainText[0] << endl; // return the first value at sub of array attained from vec
Here is small test program to clarify my understanding:
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char** argv )
{
typedef unsigned char NBYTE;
typedef vector<NBYTE*> TEST_ARRAYBYTE;
NBYTE *rgbPlaintext = NULL;
NBYTE testarray[] = {'2', '1'};
NBYTE testarray1[] = {'1', '2'};
TEST_ARRAYBYTE vec;
vec.push_back(testarray);
vec.push_back(testarray1);
rgbPlaintext = vec[0];
cout << rgbPlaintext[0] << endl;
rgbPlaintext = vec[1];
cout << rgbPlaintext[0] << endl;
}

Array Creation Problems in C++

I'm a novice programmer trying to get a head start on some classes before the summer semester starts, and I've run into this problem while trying to create a Quick Union algorithm in C++.
I've been trying to figure out why my program creates two identical arrays, despite having two separate for loops designed to create two different arrays. Whenever my program runs to completion and prints id[] and sz[], it always outputs 1 as the element at every index in both arrays.
class quickUnionUF{
private:
int id[];
int sz[];
int root(int);
public:
quickUnionUF(int, int);
bool connected(int, int);
void unionPoint(int, int);
void print();
};
quickUnionUF::quickUnionUF(int n, int b){
id[n];
sz[b];
for(int i=0;i<n;i++){
id[i] = i;
}
for(int j=0;j<b;j++){
sz[j] = 1;
}
}
For example, if I create quickUnionUF(5, 5);
id[] should now contains elements:
0, 1, 2, 3, 4
And sz[] contains elements:
1, 1, 1, 1, 1
However, the program creates an array sz[] AND array id[] with elements:
1, 1, 1, 1, 1
Any thoughts as to why this is happening?
Standard C++ does not have sizeless array members.
Use std::vector<int> as dynamically sized arrays in C++.
#include <vector>
class quickUnionUF{
private:
std::vector<int> id;
std::vector<int> sz;
int root(int);
public:
quickUnionUF(int, int);
bool connected(int, int);
void unionPoint(int, int);
void print();
};
quickUnionUF::quickUnionUF(int n, int b)
: id(n)
, sz(b)
{
for(int i=0;i<n;i++){
id[i] = i;
}
for(int j=0;j<b;j++){
sz[j] = 1;
}
}
Your code hints at a two very important mistakes:
C++ does not work like Java. int id[] is not an reference to an array of arbitrary size on the garbage collected heap. It is instead a member array of undefined size used to implement dynamic arrays (and similar features) in C99. You should never use this syntax unless you know exactly what you are doing, because it is almost guaranteed to be wrong otherwise.
id[n] does not allocate an array at all. Instead it just indexes id and discards the result.
Listen to your compiler!
First, your code should not compile due to the fact, that only the last member of a struct may be a flexible array type. In fact clang howls:
main.cpp:53:9: error: field has incomplete type 'int []'
int id[];
MSVC howls:
1>main.cpp(54): error C2229: class 'quickUnionUF' has an illegal zero-sized array
And g++ only warns (well, g++ is strange in what it accepts sometimes):
main.cpp:53:12: warning: ISO C++ forbids zero-size array ‘id’ [-Werror=pedantic]
int id[];
Note: g++ is wrong in compiling this, even if one allows flexible array members. This is defined in C99 6.7.2.1§16 and C11 6.7.2.1§18 both of which begin with (emphasis is mine):
As a special case, the last element of a structure with more than one named member may
have an incomplete array type; this is called a flexible array member. [...]
What is happening?
Well, assuming you got your code to compile anyway, it basically means the following:
Create an object with the alignment of integers, but NO elements at all. Take a peek at the following test program:
quickUnionUF q;
::std::cout << sizeof(quickUnionUF) << "\n";
::std::cout << &q << "\n" << &q.id[0] << "\n" << &q.sz[0] << "\n";
The only compiler that managed to compile this at all (gcc 4.9.0) gave the following result:
0
0x7fff1bf6274c
0x7fff1bf6274c
0x7fff1bf6274c
So, this is a zero byte object (yes, this is illegal C++, since every C++ object has a size > 0) and the first element of each array is at the same position (OUTSIDE YOUR OBJECT!). Remember, you declared id and sz to have zero elements!
Therefore, you are writing to the same arbitrary position. You can consider this the extreme case of a buffer overflow: By writing 5 integers to a zero size buffer, you are overflowing from the first zero size buffer through the second zero size buffer into memory totally not under your control.
This also explains your observed result: The second loop simply overwrites what the first did (and it still does it by corrupting your stack).
How do I fix this?
Just use a vector. You can tell it how big you want it and you can ask it to tell you when you are indexing to some position that is not yours.