Create an array when the size is a variable not a

2020-01-23 12:57发布

问题:

Here is the program:

int siz = 0;
int n = 0;
FILE* picture;
char buf[50];
char* s = "";
cout << "Getting image size" << endl;
picture = fopen("C:\\Users\\n.b\\Desktop\\c++\\TCP\\tcp_client_image_pp\\test.jpg", "r");
fseek(picture, 0, SEEK_END);
siz = ftell(picture);
cout << siz << endl; // Output 880
cout << "Sending picture size to the server" << endl;
sprintf(buf, "%d", siz);
if ((n = send(Connections[index], buf, sizeof(buf), 0)) < 0)
{
    perror("send_size()");
    exit(errno);
}
char Sbuf[siz];
cout << "Sending the picture as byte array" << endl;
fseek(picture, 0, SEEK_END);
siz = ftell(picture);
fseek(picture, 0, SEEK_SET); //Going to the beginning of the file
while (!feof(picture)) {
    n = fread(Sbuf, sizeof(char), siz, picture);
    if (n > 0) { /* only send what has been read */
        if ((n = send(Connections[index], Sbuf, siz, 0)) < 0) 
        {
            perror("send_data()");
            exit(errno);
        }
    }
    /* memset(Sbuf, 0, sizeof(Sbuf)); 
}

I need to read the file size. I know for sure that this code compiled on another compiler. How to correctly declare siz correctly so that the code compiles?

回答1:

There is no proper way to do this, as a program with any variable length array is ill-formed.

An alternative, so to speak, to a variable length array is a std::vector:

std::vector<char> Sbuf;

Sbuf.push_back(someChar);

Of course, I should mention that if you are using char specifically, std::string might work well for you. Here are some examples of how to use std::string, if you're interested.

The other alternative to a variable length array is the new operator/keyword, although std::vector is usually better if you can make use of it:

char* Sbuf = new char[siz];

delete [] Sbuf;

However, this solution does risk memory leaks. Thus, std::vector is preferred.



回答2:

You can dynamically create an array using new keyword:

char* Sbuf; // declare a char pointer Sbuf
Sbuf = new char[siz]; // new keyword creates an array and returns the adress of that array

delete Sbuf; // you have to remember to deallocate your memory when you are done

Better, more standard compatible approach would be to use smart pointers

std::unique_ptr<char[]> Sbuf = std::make_unique<char[]>(siz);