Search code examples
arrayscfor-loopc-stringssigabrt

My code runs fine with test A or test B commented out, but both are run the program crashes


#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <math.h>

void ip2array(const char* ip_str, uint8_t* ip_int) {
    int i = 0;
    char* p = (char*)ip_str;
    while (*p != '\0') {
        ip_int[i++] = (uint8_t)strtoul(p, &p, 10);
        p++;
    }
}

uint32_t ips_between (const char* start, const char* end) {
    uint8_t ip[2][4];
    ip2array(start, ip[0]);
    ip2array(end, ip[1]);

    uint32_t total = 0;
    for (int i = 0; i < 4; ++i)
        total += (ip[1][3 - i] - ip[0][3 - i]) * (uint32_t)pow(2, i * 8);

    return total;
}

int main() {
    printf("%u\n", ips_between("10.0.0.0", "10.0.0.50")); // test A
    printf("%u\n", ips_between("20.0.0.10", "20.0.1.0")); // test B
}

If I run the program with only test A or test B, the correct result is given. If the tests are run sequentially (as above) the program crashes: Process finished with exit code 134 (interrupted by signal 6: SIGABRT).

I have removed all dynamically allocated memory and double checked all the loops. When using a debugger, the program seems to crash just as it returns the total to main. I'm fairly sure printf is not involved as I tried removing that as well. The error happens consistently across three different platforms.


Solution

  • This while loop

    while (*p != '\0') {
        ip_int[i++] = (uint8_t)strtoul(p, &p, 10);
        p++;
    }
    

    can invoke undefined behavior due to this statement

        p++;
    

    when *p is equal to '\0' after processing the last number in the string because as a result there will be access memory outside the array ip_str.