C malloc valgrind的大小无效写入 [英] C malloc valgrind invalid write of size

查看:61
本文介绍了C malloc valgrind的大小无效写入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的公平分配malloc无效(以及该站点上的许多示例),但是我仍然很难指出是什么原因造成的.在这里,我有一个用于图的邻接矩阵,并且在分配时,我从valgrind得到了无效的写入(但是在整个程序中没有分段错误).我也收到无效的读取,但我认为这是由无效的先前写入引起的.

I've had my fair share malloc invalid writes (and the many examples on this site) but I still have trouble pointing out what's causing some. Here I have an adjacency matrix to use for graphs and when allocating, I get the invalid write from valgrind (but no segmentation fault throughout the program). I also get invalid reads but I assume that's caused from the invalid write prior.

FYI adj_matrix是一个类型定义的结构,其int类型用于表示顶点数量,而char **用于在头文件中声明的实际2D数组

FYI adj_matrix is a typedef'd struct with an int type for number of vertices and a char** for the actual 2D array declared in the header file

此外,我的帖子中没有包含测试文件,它所做的只是为结构分配空间并调用这些函数.

Also, not included in my post is the test file, all it does is allocate space for the struct and call these functions.

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>

#include "adj_matrix.h"

void adj_matrix_init(adj_matrix *matrix, const int num_vertices) {

    int i;
    char* temp;

    matrix->num_vertices = num_vertices;

    //INVALID WRITE & READ HERE
    if(!(matrix->matrix = malloc(num_vertices * sizeof(char *)))) { 
        fprintf(stderr, "Could not allocate space for the adjacency matrix.\n");
        exit(EXIT_FAILURE);
    }

    // THIS ONE WORKS THOUGH
    if(!(temp = calloc(num_vertices * num_vertices, sizeof(char)))) {
        fprintf(stderr, "Could not allocate space for the adjacency matrix.\n");
        exit(EXIT_FAILURE);
    }

    for(i = 0; i < num_vertices; i++) {
        (matrix->matrix)[i] = temp + (i * num_vertices); // INVALID READ
    }
}

void adj_matrix_destroy(adj_matrix *matrix) {

    free(matrix->matrix[0]); // INVALID READ
    free(matrix->matrix);
    free(matrix);
}

void adj_matrix_add_edge(adj_matrix *matrix, const int from_node, const int to_node) {
    matrix->matrix[from_node - 1][to_node - 1] = 1; // INVALID READ
}

void adj_matrix_remove_edge(adj_matrix *matrix, const int from_node, const int to_node) {
    matrix->matrix[from_node - 1][to_node -1] = 0;
}

bool adj_matrix_check_edge(const adj_matrix *matrix, const int from_node, const int to_node) {
    return (matrix->matrix[from_node - 1][to_node -1] ? true : false);
}

size_t adj_matrix_min(const size_t val1, const size_t val2) {
    return (val1 <= val2) ? val1 : val2;
}

size_t adj_matrix_to_string(const adj_matrix *matrix, char *buffer, const size_t buffer_size) {
    const size_t terminator = adj_matrix_min(buffer_size, (size_t)pow((matrix->num_vertices+1) + 1, 2));
    int i, j, count = 0;

    printf("Buffer size: %zd\nMatrix size (plus null character): %f\nMinimum: %zd\n", buffer_size, pow((matrix->num_vertices + 1), 2), terminator);

    for(i = 0; i < matrix->num_vertices; i++) {
        for(j = 0; j < matrix->num_vertices; j++) {
            printf("TEST1: %s\n info: %d\n", buffer, matrix->matrix[i][1]); // JUST TESTING VALUES
            if( (count - 1) < terminator) {
                if(matrix->matrix[i][j]) {
                    printf("Got in with true\n");
                    buffer[count++] = '1';
                } else {
                    printf("Got in with false\n");
                    buffer[count++] = '0';
                }
                buffer[count] = '\0';
            }
            else {
                buffer[buffer_size - 1] = '\0';
                return terminator;
            }
            printf("TEST2: %s\n", buffer);
        }
        if( (count - 1) < terminator ) {
            buffer[count++] = '\n';
            buffer[count] = '\0';
        }
        else {
            buffer[buffer_size - 1] = '\0';
            return terminator;
        }
    }
    return terminator;
}

VALGRIND:

==5590== Memcheck, a memory error detector
==5590== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==5590== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==5590== Command: ./test-adj_matrix
==5590== 
==5590== Invalid write of size 8
==5590==    at 0x40080C: adj_matrix_init (adj_matrix.c:16)
==5590==    by 0x400718: main (test_adjmatrix.c:12)
==5590==  Address 0x51f10a8 is 0 bytes after a block of size 8 alloc'd
==5590==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x400703: main (test_adjmatrix.c:10)
==5590== 
==5590== Invalid read of size 8
==5590==    at 0x400814: adj_matrix_init (adj_matrix.c:16)
==5590==    by 0x400718: main (test_adjmatrix.c:12)
==5590==  Address 0x51f10a8 is 0 bytes after a block of size 8 alloc'd
==5590==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x400703: main (test_adjmatrix.c:10)
==5590== 
==5590== Invalid read of size 8
==5590==    at 0x4008A7: adj_matrix_init (adj_matrix.c:27)
==5590==    by 0x400718: main (test_adjmatrix.c:12)
==5590==  Address 0x51f10a8 is 0 bytes after a block of size 8 alloc'd
==5590==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x400703: main (test_adjmatrix.c:10)
==5590== 
==5590== Invalid read of size 8
==5590==    at 0x400925: adj_matrix_add_edge (adj_matrix.c:39)
==5590==    by 0x40072E: main (test_adjmatrix.c:14)
==5590==  Address 0x51f10a8 is 0 bytes after a block of size 8 alloc'd
==5590==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x400703: main (test_adjmatrix.c:10)
==5590== 
==5590== Invalid read of size 8
==5590==    at 0x400925: adj_matrix_add_edge (adj_matrix.c:39)
==5590==    by 0x400744: main (test_adjmatrix.c:15)
==5590==  Address 0x51f10a8 is 0 bytes after a block of size 8 alloc'd
==5590==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x400703: main (test_adjmatrix.c:10)
==5590== 
==5590== Invalid read of size 8
==5590==    at 0x400925: adj_matrix_add_edge (adj_matrix.c:39)
==5590==    by 0x40075A: main (test_adjmatrix.c:16)
==5590==  Address 0x51f10a8 is 0 bytes after a block of size 8 alloc'd
==5590==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x400703: main (test_adjmatrix.c:10)
==5590== 
Buffer size: 26
Matrix size (plus null character): 25.000000
Minimum: 26
==5590== Invalid read of size 8
==5590==    at 0x400A9F: adj_matrix_to_string (adj_matrix.c:62)
==5590==    by 0x400772: main (test_adjmatrix.c:18)
==5590==  Address 0x51f10a8 is 0 bytes after a block of size 8 alloc'd
==5590==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x400703: main (test_adjmatrix.c:10)
==5590== 
==5590== Conditional jump or move depends on uninitialised value(s)
==5590==    at 0x4E7D3B1: vfprintf (vfprintf.c:1630)
==5590==    by 0x4E858D8: printf (printf.c:35)
==5590==    by 0x400AD5: adj_matrix_to_string (adj_matrix.c:62)
==5590==    by 0x400772: main (test_adjmatrix.c:18)
==5590==  Uninitialised value was created by a heap allocation
==5590==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x4006F5: main (test_adjmatrix.c:8)
==5590== 
TEST1: 
 info: 1
==5590== Conditional jump or move depends on uninitialised value(s)
==5590==    at 0x4E7D3B1: vfprintf (vfprintf.c:1630)
==5590==    by 0x4E858D8: printf (printf.c:35)
==5590==    by 0x40078B: main (test_adjmatrix.c:20)
==5590==  Uninitialised value was created by a heap allocation
==5590==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x4006F5: main (test_adjmatrix.c:8)
==5590== 
==5590== Invalid read of size 8
==5590==    at 0x400961: adj_matrix_remove_edge (adj_matrix.c:43)
==5590==    by 0x4007A1: main (test_adjmatrix.c:22)
==5590==  Address 0x51f10a8 is 0 bytes after a block of size 8 alloc'd
==5590==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x400703: main (test_adjmatrix.c:10)
==5590== 
Buffer size: 26
Matrix size (plus null character): 25.000000
Minimum: 26
==5590== Invalid read of size 8
==5590==    at 0x400A9F: adj_matrix_to_string (adj_matrix.c:62)
==5590==    by 0x4007B9: main (test_adjmatrix.c:24)
==5590==  Address 0x51f10a8 is 0 bytes after a block of size 8 alloc'd
==5590==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x400703: main (test_adjmatrix.c:10)
==5590== 
==5590== Conditional jump or move depends on uninitialised value(s)
==5590==    at 0x4E7D3B1: vfprintf (vfprintf.c:1630)
==5590==    by 0x4E858D8: printf (printf.c:35)
==5590==    by 0x400AD5: adj_matrix_to_string (adj_matrix.c:62)
==5590==    by 0x4007B9: main (test_adjmatrix.c:24)
==5590==  Uninitialised value was created by a heap allocation
==5590==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x4006F5: main (test_adjmatrix.c:8)
==5590== 
TEST1: 
 info: 0
==5590== Invalid read of size 8
==5590==    at 0x4008E6: adj_matrix_destroy (adj_matrix.c:33)
==5590==    by 0x4007C5: main (test_adjmatrix.c:26)
==5590==  Address 0x51f10a8 is 0 bytes after a block of size 8 alloc'd
==5590==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x400703: main (test_adjmatrix.c:10)
==5590== 
==5590== Invalid read of size 8
==5590==    at 0x4008F9: adj_matrix_destroy (adj_matrix.c:34)
==5590==    by 0x4007C5: main (test_adjmatrix.c:26)
==5590==  Address 0x51f10a8 is 0 bytes after a block of size 8 alloc'd
==5590==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x400703: main (test_adjmatrix.c:10)
==5590== 
==5590== Invalid free() / delete / delete[] / realloc()
==5590==    at 0x4C2A82E: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x4007D1: main (test_adjmatrix.c:28)
==5590==  Address 0x51f10a0 is 0 bytes inside a block of size 8 free'd
==5590==    at 0x4C2A82E: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x400910: adj_matrix_destroy (adj_matrix.c:35)
==5590==    by 0x4007C5: main (test_adjmatrix.c:26)
==5590== 
==5590== 
==5590== FILE DESCRIPTORS: 3 open at exit.
==5590== Open file descriptor 2: /dev/pts/4
==5590==    <inherited from parent>
==5590== 
==5590== Open file descriptor 1: /dev/pts/4
==5590==    <inherited from parent>
==5590== 
==5590== Open file descriptor 0: /dev/pts/4
==5590==    <inherited from parent>
==5590== 
==5590== 
==5590== HEAP SUMMARY:
==5590==     in use at exit: 26 bytes in 1 blocks
==5590==   total heap usage: 4 allocs, 4 frees, 82 bytes allocated
==5590== 
==5590== 26 bytes in 1 blocks are definitely lost in loss record 1 of 1
==5590==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5590==    by 0x4006F5: main (test_adjmatrix.c:8)
==5590== 
==5590== LEAK SUMMARY:
==5590==    definitely lost: 26 bytes in 1 blocks
==5590==    indirectly lost: 0 bytes in 0 blocks
==5590==      possibly lost: 0 bytes in 0 blocks
==5590==    still reachable: 0 bytes in 0 blocks
==5590==         suppressed: 0 bytes in 0 blocks

test_adjmatrix.c

test_adjmatrix.c

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "adj_matrix.h"

int main() {
    char* temp = malloc((5*5+1)*sizeof(char));

    adj_matrix *matrix = malloc(sizeof(matrix));

    adj_matrix_init(matrix, 4);

    adj_matrix_add_edge(matrix, 2, 1);
    adj_matrix_add_edge(matrix, 1, 2);
    adj_matrix_add_edge(matrix, 3, 4);

    adj_matrix_to_string(matrix, temp, (5*5+1) * sizeof(char));

    printf("%s", temp);

    adj_matrix_remove_edge(matrix, 1, 2);

    adj_matrix_to_string(matrix, temp, (5*5+1) * sizeof(char));

    adj_matrix_destroy(matrix);

    free(matrix);
    return 0;
}

推荐答案

以下内容似乎不正确:

adj_matrix *matrix = malloc(sizeof(matrix));

它正在分配4个字节(假定为32位编译器).可能应该是sizeof( adj_matrix ).

It is allocating 4 bytes (assuming 32-bit compiler). Probably should be sizeof( adj_matrix ).

这篇关于C malloc valgrind的大小无效写入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆