malloc为List分配内存

时间:2013-07-06 12:23:53

标签: c malloc dynamic-memory-allocation

我有一个自定义结构

typedef struct node
{

   struct node *next;
   int vertex;
}node;

typedef struct {

    int numberOfNodes;  
    int *visited; 
    int numberOfEdges ;

    node **ppLists;
} adjacencyList;

我正在尝试使用以下代码为邻接列表分配内存,numberOfNodes为1000.

adjacencyList *createAdjList(int numberOfNodes)
{
    int i;
    adjacencyList *newList;

    //Allocate memory for list and the array of nodes

    newList=(adjacencyList *)malloc(sizeof(adjacencyList));
    newList->numberOfNodes=numberOfNodes;
    newList->ppLists=(node**)malloc(numberOfNodes*sizeof(node));


    for (i = 0; i < newList->numberOfNodes; i++) {
      newList->ppLists[i] = (node*)malloc(sizeof(node)*newList->numberOfNodes);
    }

    return newList;
}

代码成功符合,但是在运行时遇到分段错误。我使用了gdb,这是后面的跟踪。

#0  0x00007ffff7a51425 in __GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x00007ffff7a54b8b in __GI_abort () at abort.c:91
#2  0x00007ffff7a9915d in __malloc_assert (assertion=<optimized out>, file=<optimized out>, line=<optimized out>, function=<optimized out>) at malloc.c:300
#3  0x00007ffff7a9c674 in sYSMALLOc (av=0x7ffff7dd3720, nb=16016) at malloc.c:2448
#4  _int_malloc (av=0x7ffff7dd3720, bytes=16000) at malloc.c:3903
#5  0x00007ffff7a9dfc5 in __GI___libc_malloc (bytes=16000) at malloc.c:2924
#6  0x0000000000401c08 in createAdjList (numberOfNodes=1000) at /home/merlyn/projects/soft/AdjacencyList.c:25
#7  0x0000000000401155 in createAdjListFromMatrix (pAdjMatrix=0x605010) at /home/merlyn/projects/soft/tools.c:86
#8  0x0000000000401017 in main (argc=2, argv=0x7fffffffdf18) at /home/merlyn/projects/soft/main.c:22

的valgrind

==6328== Memcheck, a memory error detector
==6328== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==6328== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==6328== Command: ./exercise
==6328== 
==6328== Invalid write of size 4
==6328==    at 0x4E8892D: _IO_vfscanf (vfscanf.c:1857)
==6328==    by 0x4E903EA: __isoc99_fscanf (isoc99_fscanf.c:35)
==6328==    by 0x401A15: readAdjMatrixFromFile (AdjacencyMatrix.c:138)
==6328==    by 0x400FF5: main (main.c:14)
==6328==  Address 0x51f3675 is 997 bytes inside a block of size 1,000 alloc'd
==6328==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6328==    by 0x4019AA: readAdjMatrixFromFile (AdjacencyMatrix.c:126)
==6328==    by 0x400FF5: main (main.c:14)
==6328== 
1000 
==6328== Conditional jump or move depends on uninitialised value(s)
==6328==    at 0x401D68: addEdgeToAdjList (AdjacencyList.c:75)
==6328==    by 0x4011A5: createAdjListFromMatrix (tools.c:77)
==6328==    by 0x401016: main (main.c:22)
==6328== 
==6328== 
==6328== HEAP SUMMARY:
==6328==     in use at exit: 17,098,448 bytes in 7,154 blocks
==6328==   total heap usage: 7,156 allocs, 2 frees, 17,099,584 bytes allocated
==6328== 
==6328== LEAK SUMMARY:
==6328==    definitely lost: 48 bytes in 2 blocks
==6328==    indirectly lost: 17,098,400 bytes in 7,152 blocks
==6328==      possibly lost: 0 bytes in 0 blocks
==6328==    still reachable: 0 bytes in 0 blocks
==6328==         suppressed: 0 bytes in 0 blocks
==6328== Rerun with --leak-check=full to see details of leaked memory
==6328== 
==6328== For counts of detected and suppressed errors, rerun with: -v
==6328== Use --track-origins=yes to see where uninitialised values come from
==6328== ERROR SUMMARY: 3994 errors from 2 contexts (suppressed: 2 from 2

main .c

#include "AdjacencyList.h"
#include "AdjacencyMatrix.h"
#include "tools.h"

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


int main(int argc, char* argv[])
{

    // load the matrix 

    adjacencyMatrix *newAdjMatrix=readAdjMatrixFromFile(argv[1]) ;

    // A test to check if the matrix has actually been loaded

    writeAdjMatrixToFile(newAdjMatrix, "123.txt");

    // covert matrix to list

    adjacencyList *newAdjList = createAdjListFromMatrix(newAdjMatrix);

    // perform reachablity for matrix

    //checkReachabilityMatrix(newAdjMatrix,0) ;

    // perform reachability for list

   return 0;
}

adjacencyMatrix *readAdjMatrixFromFile(char *pFilename)
{

    adjacencyMatrix *newAdjMatrix;
    newAdjMatrix = (adjacencyMatrix *) malloc(sizeof(adjacencyMatrix));
    FILE *pFile;
    pFile = fopen("/home/merlyn/projects/soft/Graph.txt", "r");
    char ch;

    if(pFile==NULL)
    {
        printf("Cannot open File");

    }
    //First Character will have number of nodes
    int i,j;
    //fgetc(
    fscanf(pFile, "%d",&i);

    //newAdjMatrix->numberOfNodes=((int)fgetc(pFile));

    newAdjMatrix->numberOfNodes = i;
    newAdjMatrix->ppMatrix = (bool**) malloc(sizeof(bool*)*newAdjMatrix->numberOfNodes);

    int idx;
    for (idx = 0; idx < newAdjMatrix->numberOfNodes; idx++) 
        newAdjMatrix->ppMatrix[idx] = (bool*) malloc(sizeof(bool)*newAdjMatrix->numberOfNodes);

    i=0;//rows
    j=0;//columns
    //iterate over entire file
    for(i=0;i<newAdjMatrix->numberOfNodes;i++)
    {
      for(j=0;j<newAdjMatrix->numberOfNodes;j++)

        //keep adding elements to the column for ith row
          fscanf(pFile, "%d",&newAdjMatrix->ppMatrix[i][j]);

    }

    fclose(pFile);
    return newAdjMatrix;
}

typedef struct
{

    int numberOfNodes;

    bool **ppMatrix;
} adjacencyMatrix;

tools.c

adjacencyList *createAdjListFromMatrix(adjacencyMatrix *pAdjMatrix)
{
    //create a adjacencyList with the same number of nodes as adjacencyMatrix

    adjacencyList *pNewadjacencyList=createAdjList(pAdjMatrix->numberOfNodes);

    // now we move from row to row and create a list for every 1
    int i,j;

    for( i=0;i<pAdjMatrix->numberOfNodes;i++)
    {
        for( j=0;j<pAdjMatrix->numberOfNodes;j++)
        {
            //If an edge is found then create a node
            if(pAdjMatrix->ppMatrix[i][j]==1)
            {
                addEdgeToAdjList(pNewadjacencyList, i, j);

            }

        }
    }
    return pNewadjacencyList;
}

2 个答案:

答案 0 :(得分:0)

这一行:

newList->ppLists=(node**)malloc(numberOfNodes*sizeof(node));

应改为:

newList->ppLists = malloc(numberOfNodes*sizeof(node*));

原因是,你有一个指向节点的数组。所以这个数组的实际类型是指向节点(node*)的指针。这是您要为其分配内存的类型。在malloc已分配内存后,它将返回指向该类型的指针,因此您将获得指向指针= node**

的指针

在C语言中,您不必像{c +}那样转换由void *返回的malloc

答案 1 :(得分:0)

下面:

newList->ppLists=(node**)malloc(numberOfNodes*sizeof(node));

您要求malloc返回指向某些节点的指针。但是因为你有一个指向ppLists指针的声明你想要以下面的方式使用malloc(考虑到H2CO3的建议不要强制转换结果):

newList->ppLists = malloc(numberOfNodes * sizeof *newList->ppLists);

这要求malloc返回一个指向node类型结构的指针数组,而不是一组所述结构。