Home > Back-end >  Ensuring data is properly stored in c array
Ensuring data is properly stored in c array

Time:03-29

I have a large code I'm trying to integrate into an existing program. For this, I need to work with c 2d and 1d arrays. I'm most familiar with python; if I tried

import numpy as np
x = np.zeros(10)
x[20] = 3
print(x[15])

Both lines 3 and 4 would cause an error to occur. In c , this doesn't cause an error, instead a segfault will likely occur somewhere in the code (or the computed answer is meaningless). My question is, how can I ensure memory assignment/access in a c array is correct? Are the compiler options or debugging tools that would help with this? I am using g to compile the code.

CodePudding user response:

With raw arrays, there is no way except if you keep track of the actual size yourself.

In C , you only pay for what you use. In other words, the bounds checking is up to the developer to implement so that it won't penalize someone who does not actually need it.

A good practice is to not use raw arrays but use standard containers instead (std::array, std::vector, ...). They own their data and keep track of the size for you.

With standard containers, there is an at() member function that throws an std::out_of_range exception if you try to access an out of bounds index.
On the other hand, if you don't want to handle the exception, you still can do the bounds checking manually using the size() member function.


One valid implementation of your example bay be:

std::vector<int> x(10, 0); // Vector of 10 elements initialized with value 0
  • Bounds checking with exception handling:
try
{
    x.at(12) = 3; // at()
}
catch(std::exception & e)
{
    std::cout << e.what() << std::endl;
}
  • Manual bounds checking:
if(12 < x.size())
    x[12] = 3; // operator[]

Note: std::vector requires to #include <vector> and std::array requires to #include <array>.

CodePudding user response:

The compiler will warn you if you use a literal index like shown in your question:

#include <stdio.h>

int main() {
        int thing[2] = {0};
        printf("%d", thing[3]);
        return 0;
}
test.cpp:5:15: warning: array index 3 is past the end of the array (which contains 2 elements) [-Warray-bounds]
        printf("%d", thing[3]);
                     ^     ~
test.cpp:4:2: note: array 'thing' declared here
        int thing[2] = {0};
        ^
1 warning generated.

It will not, however, generate an error if you use a variable to index into the array, and the value of that variable is out-of-range. For example:

#include <stdio.h>

int main() {
    int thing[2] = {0};
    int index = 3;
    printf("%d", thing[index]);
    return 0;
}

The behaviour here is undefined, and the compiler won't let you know. The best you can do in these cases is put a check in place before the array access.

  • Related