Coop4Free
Coop4Free

Reputation: 35

Why does my array values not match with the global variables here?

I have a problem here :( I create here multiple global variables and put them into an array. In funktion extractLabel() I fill these variables with binary code values per variable = binarycode. I print them out and everything is alright. Then I print the same variables out from the array. But there the variables have the values 0. But shouldn't these variables have the same value in the array, too? If not, how I could fix this?

Thank you for helping!

#include <iostream>
#include <vector>
#include <sstream>
#include <string>
#include <array>
#include <math.h>
#include <algorithm>
#include "Client.hpp"



static long long a_word = 4294967295;
static long long c_word;
static long long c_label1;
static long long c_label2;
static long long c_label3;
static long long c_label4;
static long long c_label5;
static long long c_label6;
static long long c_label7;
static long long c_label8;
static std::vector<bool> binCode;
static std::array<long long, 8> c_tokens = {c_label1, c_label2, c_label3, c_label4, c_label5, c_label6, c_label7, c_label8};



void executeClient() {
    receiveValue();
    calculateDecBin();
    extractLabel();
}

void receiveValue() {
    c_word = a_word;
}

void calculateDecBin() {
    while (c_word) {
        int rest = c_word % 2;
        c_word = c_word / 2;
        binCode.push_back(rest);
    }
    std::reverse(binCode.begin(), binCode.end());
}

void extractLabel() {

    std::cout << "Label values:" << std::endl;
    for(int i = 0; i < 8; i++) {
        c_label1 = stoll(std::to_string(c_label1) + std::to_string(binCode[i]));
    }
    std::cout << c_label1 << std::endl;

    for(int i = 8; i < 10; i++) {
        c_label2 = stoll(std::to_string(c_label2) + std::to_string(binCode[i]));
    }
    std::cout << c_label2 << std::endl;

    for(int i = 10; i < 26; i++) {
        c_label3 = stoll(std::to_string(c_label3) + std::to_string(binCode[i]));
    }
    std::cout << c_label3 << std::endl;

    for(int i = 26; i < 27; i++) {
        c_label4 = stoll(std::to_string(c_label4) + std::to_string(binCode[i]));
    }
    std::cout << c_label4 << std::endl;

    for(int i = 27; i < 28; i++) {
        c_label5 = stoll(std::to_string(c_label5) + std::to_string(binCode[i]));
    }
    std::cout << c_label5 << std::endl;

    for(int i = 28; i < 29; i++) {
        c_label6 = stoll(std::to_string(c_label6) + std::to_string(binCode[i]));
    }
    std::cout << c_label6 << std::endl;

    for(int i = 29; i < 31; i++) {
        c_label7 = stoll(std::to_string(c_label7) + std::to_string(binCode[i]));
    }
    std::cout << c_label7 << std::endl;

    for(int i = 31; i < 32; i++) {
        c_label8 = stoll(std::to_string(c_label8) + std::to_string(binCode[i]));
    }
    std::cout << c_label8 << std::endl;


    std::cout << "array values:" << std::endl;
    for(int i = 0; i < c_tokens.size(); i++) {
        std::cout << c_tokens[i] << std::endl;
    }
}

Upvotes: 0

Views: 90

Answers (4)

Jeffrey
Jeffrey

Reputation: 11410

C++ has copy semantics.

When you do:

static std::array<long long, 8> c_tokens = {c_label1, c_label2, c_label3, c_label4, c_label5, c_label6, c_label7, c_label8};

(this gets executed early on)

The value of the variables are copied into a new c_tokens variable. From this point on, changing either c_tokens or c_label... will not affect the other.

You could store references in the array using reference wrappers:

static std::array<std::reference_wrapper<long long>, 8> c_tokens = {c_label1, c_label2, c_label3, c_label4, c_label5, c_label6, c_label7, c_label8}; // actually works, but heavy 

In that case, what the array would contain is a reference (a sort of link) to the specified variable. Access via either the array or individual variable would immediately affect the other.

But without a larger look at your project it's not clear whether that's the right approach or not. Having a list of variables with a number at the end is a code smell.

Upvotes: 1

Botje
Botje

Reputation: 30840

Here is a slightly less verbose way of writing that code, which sidesteps the variable question entirely and makes it clear what goes where: (assuming c_tokens is a vector. If you want a static array just assign to indices)

long long pack(std::vector<bool>::const_iterator it, int count) {
    long long res = 0;
    while (count-- > 0) {
        res = res * 10 + *it;
    }
    return res;
}

void foo() {
    c_tokens.emplace_back(pack(binCode.cbegin() + 0, 8));
    c_tokens.emplace_back(pack(binCode.cbegin() + 8, 2));
    c_tokens.emplace_back(pack(binCode.cbegin() + 10, 16));
    c_tokens.emplace_back(pack(binCode.cbegin() + 26, 1));
    c_tokens.emplace_back(pack(binCode.cbegin() + 27, 1));
    c_tokens.emplace_back(pack(binCode.cbegin() + 28, 1));
    c_tokens.emplace_back(pack(binCode.cbegin() + 29, 2));
    c_tokens.emplace_back(pack(binCode.cbegin() + 31, 1));
}

Upvotes: 0

Serge Ballesta
Serge Ballesta

Reputation: 148965

You are making a confusion between values and references. The c_tokens array is initialized with the current values of the c_labeli variables. As they are static, they are initialized to 0, which explains that you find 0 values in the array.

But when you later change the values of the c_labeli variables, they are completely distinct from the array, and nothing is changed in c_tokens.

Upvotes: 1

JoKing
JoKing

Reputation: 470

The variables are not in the array! You created an array from the values of the variables that they had at the time you created the array. You can be lucky, that the values are 0 and not something else, because the variables were uninitialized when you used them to fill the array. The variables and the array are in two different memory areas, if you change one, the other one remains unchanged.

Upvotes: 0

Related Questions