Printing a vector... Differences between C++ and C... Where did I go wrong?

Asked

Viewed 110 times

2

I’m having problems printing vector structs in C, in C++ it worked...

First I will show the version in C with problems (in the execution because compiles without errors)

CACHE cache = createCache(descricao); //chamada da main

printaCache(cache); //chamada da main

Now the functions:

CACHE createCache(CACHEDESC desc)
{
    int i, associatividade, contador=0;
    CACHE *vec;
    vec = malloc(desc.number_of_lines * (sizeof vec));

    associatividade = desc.associativity, contador = 0;
    for (i = 0; i < desc.number_of_lines; i++) {

        CACHE auxiliar;
        auxiliar.tag = 0;
        auxiliar.index = contador;
        auxiliar.data = 0;
        auxiliar.time = clock();//start times
        vec[i] = auxiliar;
        --associatividade;
        if (associatividade == 0)
        {
            associatividade = desc.associativity;
            contador++;
        }
    }
    return *vec;
}

void printaCache(CACHE vec)
{
    int i;
    for(i=0;i<sizeof(vec);i++)
    {
         printf("%d \t %d \t %d \t %d\n",i, vec);
    }
}

These functions compile without errors or warnings, but when running the program it crashes...

The C++ code that works 100% is:

void printCache(vector<CACHE> cache){
    for(int i=0; i<cache.size(); i++){
        cout<< i<< "\t "<< cache[i].tag << " \t " << cache[i].index <<"\t "<< cache[i].time  << "\n";
    }
 } 

vector<CACHE> createCache(CACHECONFIG conf){
    vector<CACHE> vec;
    int assoc = conf.associativity, count=0;
    for(int i=0; i<conf.numLines; i++){
        CACHE aux;
        aux.valido=true;
        aux.tag=0;
        aux.index=count;
        aux.dado=0;
        aux.time = clock();//inicio dos tempos
        vec.push_back(aux);
        if(--assoc==0){
            assoc=conf.associativity;
            count++;
             } 
        }
        printCache(vec);
        return vec;
    }

Both languages are using structs:

typedef struct cache{
    int tag;
    int index;
    int dado;
    clock_t time;
}CACHE;

Anyway, I’d like to know what I’m missing in code C so I don’t get the same result as code C++

  • 1

    I would tell you not to invent the wheel. If the program needs to be in C use the Glib (see GArray) or Gnulib, [see that mobile). Implementing nail collections for a real program (as opposed to an exercise) quickly becomes a difficult task.

1 answer

2


In the answer to your previous question I said it was not so simple to make this conversion. There will be a lot of different situation that will need proper treatment. The solution that seems simple is not very suitable. This code will become a maintenance nightmare. But let’s try to solve one problem at a time, even if it’s not the right thing to do.

The biggest problem there is that size() of vector does not convert to sizeof. The first actually gives the size in number of vector elements. The second gives the size in number of bytes of a known data structure at compile time. Since this structure is dynamically cracked at runtime, it simply cannot use the sizeof. Actually there’s no way to figure out the size.

The naive solution would be to carry the size back and forth so it can be used. But this will make the whole code difficult. The right thing would be to do what I said in that answer and create your own vector where you have the same semantics, so you can do the conversion peacefully without a headache. That is, the naive response there at previous question didn’t work out, except that she had mistakes and it doesn’t work as you imagine. I knew this would happen.

The right thing is to make a complete structure, but I’m going to give you the solution just to this problem, which seems to be what you want. But note that I will make the solution as naive as possible, other problems will occur later. As I don’t have enough information to test I can’t guarantee that everything is right. I can only answer on top of what the question gives me.

Usually when it’s exercise I don’t even care that code op is not as appropriate as possible, in cases it seems that going to use on something real would have to make a much more robust code. But also the whole solution is wrong, so it’s not worth the effort to try to do the right thing. This code will work well in most situations, but if some extraordinary situation happens, it will be a disaster.

If later you have to create other vectors of other types, it will complicate more.

Create a structure to maintain the vector with its size:

typedef struct {
    size_t size;
    CACHE *vector;
} VectorCache

VectorCache *createCache(CACHEDESC desc) {
    VectorCache *vec = malloc(desc.number_of_lines * (sizeof CACHE));
    int associatividade = desc.associativity
    int contador = 0;
    for (int i = 0; i < desc.number_of_lines; i++) {
        CACHE auxiliar;
        auxiliar.tag = 0;
        auxiliar.index = contador;
        auxiliar.data = 0;
        auxiliar.time = clock();//start times
        memcpy(vec.vector[i], auxiliar, sizeof(auxiliar));
        --associatividade;
        if (associatividade == 0) {
            associatividade = desc.associativity;
            contador++;
        }
    }
    return vec;
}

void printaCache(VectorCache vec) {
    for (int i = 0; i < vec.size; i++) printf("%d \t %d \t %d \t %d\n", i, vec.vector[i].tag, vec.vector[i].index, vec.vector[i].time);
}

I put in the Github for future reference.

The impression of time probably won’t work out the way you expect.

I hope you know where to put the free() necessary to have neither memory leakage nor dangling Pointer.

Reinforce that this is the naive solution and that Anthony Accioly’s comment is quite pertinent, so prefer to use a library that has a structure similar to vector of the C++.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.