简体   繁体   中英

Why does my pointer change by a fixed number?

I have defined my own type. It contains a pointer to an array, as well as how many items are in that array

struct neighborList
{
    unsigned int nNeighbors;
    unsigned int* pNeighbors; 
};

These get instantiated, populated, and eventually I want to go back through them. Then something very strange happens. I think screenshots are better than words here.

在此处输入图片说明

I've shown the next statement to execute. I have an array of the aforementioned data type, and the one under consideration here has 1 neighbor and the address of that 1 neighbor is 0x107a28; Cool. But what actually gets assigned to pLook?

在此处输入图片说明

The address is always off by 0x40. Has anyone seen anything like this? Help here is appreciated.

EDIT: Here's the whole thing since several people want to see it.

#include "stdafx.h"
#include <stdlib.h>
#include <time.h>

//#define NVERTEX 875714
#define NVERTEX 9

struct linkedNode
{
    unsigned int node;
    linkedNode* pNextLinkedNode;
    linkedNode* pPrevLinkedNode; 
};

struct neighborList
{
    unsigned int nNeighbors;
    unsigned int* pNeighbors; 
};

struct linkedNodeList
{
    linkedNode* pHead;
    linkedNode* pTail;
};

void populateNeighbors(neighborList* pNeighborList, FILE* fp);
void DFSLoop(neighborList* pNeighborList, linkedNode* pOutput, unsigned int nNodes); 
void append(linkedNodeList* pLinkedList, unsigned int node);

void DFSLoop(neighborList* pNeighborList, linkedNodeList* pOutput, unsigned int nNodes)
{
    bool* visitedArray;
    bool* cashedArray;
    unsigned int* leaderArray;
    unsigned int* finishingTimes;
    unsigned int t = 0; 

    visitedArray = (bool*)malloc(nNodes*sizeof(bool));
    cashedArray = (bool*)malloc(nNodes*sizeof(bool)); 
    leaderArray = (unsigned int*)malloc(nNodes*sizeof(unsigned int)); 
    finishingTimes = (unsigned int*)malloc(nNodes*sizeof(unsigned int)); 

    //initialize all arrays to all false/0
    for (unsigned int i = 0; i < nNodes; i++)
    {
        visitedArray[i] = false;
        cashedArray[i] = false; 
        leaderArray[i] = 0;
        finishingTimes[i] = 0;
    }

    //firstly, pick a starting node and put it on the linkedList
    //initialize head and tail
    (pOutput->pHead)->node = 1;
    (pOutput->pHead)->pNextLinkedNode = NULL;
    (pOutput->pHead)->pPrevLinkedNode = NULL;

    (pOutput->pTail)->node = 1;
    (pOutput->pTail)->pNextLinkedNode = NULL;
    (pOutput->pTail)->pPrevLinkedNode = NULL;

    unsigned int curNode = (pOutput->pTail)->node;
    for (;;)
    {
        //Start DFS
        //#1 If current node under consideration has an unexplored neighbor, make it the new tail and repeat
        //   If not, current node is cashed. Set it's finishing time, and leader. Work back through the list
        //   Until you find a node with an unexplored neighbor
        unsigned int nNeighbors = pNeighborList[curNode].nNeighbors;

        for (unsigned int i = 0; i < nNeighbors; i++)
        {
            unsigned int* pLook = (pNeighborList[curNode]).pNeighbors;
            unsigned int neighbor = pLook[0];
            /*
            unsigned int nodeUnderConsideration = (pNeighborList[curNode].pNeighbors)[i];

            if ( !cashedArray[nodeUnderConsideration])
            {
                append(pOutput, (pNeighborList[curNode].pNeighbors)[i]); 
                curNode = (pOutput->pTail)->node;
                continue; 
            }
            */
        }


        //#2 If you make it back to the head and have no unexplored neighbors, pick new vertex (if unvisited) and repeat



    }


    free(visitedArray);
    free(cashedArray); 
    free(leaderArray);
    free(finishingTimes); 
}

int _tmain(int argc, _TCHAR* argv[])
{
    //open file
    FILE* fp;
    FILE* fpRev;
    //fp = fopen("SCC.txt", "rb"); 
    //fpRev = fopen("SSCrev.txt", "rb"); 
    fp = fopen("SSCsmall1.txt", "rb"); 
    fpRev = fopen("SSCsmall1rev.txt", "rb");

    /* read file. When reading, keep track of how much memory to malloc */
    /* for each vertex */
    neighborList* pAllEdges;
    neighborList* pAllEdgesRev;
    pAllEdges = (neighborList*)malloc(NVERTEX*sizeof(neighborList)); 
    pAllEdgesRev = (neighborList*)malloc(NVERTEX*sizeof(neighborList)); 

    populateNeighbors(pAllEdges, fp);
    populateNeighbors(pAllEdgesRev, fpRev); 

    //instantiate pointers for linkedlists needed for DFS
    linkedNodeList NodesFirstPass, NodesSecondPass;
    NodesFirstPass.pHead = (linkedNode*)malloc(sizeof(linkedNode)); 
    NodesFirstPass.pTail = NodesFirstPass.pHead; 
    NodesSecondPass.pHead = (linkedNode*)malloc(sizeof(linkedNode)); 
    NodesSecondPass.pTail = NodesSecondPass.pHead; 

    DFSLoop(pAllEdges, &NodesFirstPass, NVERTEX); 

    free(pAllEdges); 
    free(pAllEdgesRev); 
    return 0;
}

void populateNeighbors(neighborList* pNeighborList, FILE* fp)
{
    unsigned int v1 = 1;
    unsigned int v2 = 1;

    unsigned int v1_next = 1;
    unsigned int v2_next = 1; 
    unsigned int neighbors [1000]; 
    fscanf(fp, "%u", &v1_next); 
    fscanf(fp, "%u", &v2_next); 

    for (unsigned int i = 0; i < (NVERTEX - 1); i++)
    {
        //initialize nNeigbors to 0
        unsigned int nNeighbors = 0;

        for (;;)
        {
            //if v1_next is a different vertex then v1, then copy v1_next to v1, 
            //malloc what we need to, copy over the array and continue
            if (v1_next != v1)
            {
                pNeighborList[i].nNeighbors = nNeighbors; 

                if (nNeighbors != 0) 
                {
                    pNeighborList[i].pNeighbors = (unsigned int*)malloc(nNeighbors * sizeof(unsigned int));

                    for (unsigned int j = 0; j < nNeighbors; j++)
                    {
                        pNeighborList[i].pNeighbors[j] = neighbors[j]; 
                    }

                }

                v1++;
                break;
            }

            //else, increment the neighbor count for this particular vertex and continue
            //within this loop, getting new neighbors (edges)
            else
            {
                neighbors[nNeighbors] = v2_next; 
                nNeighbors++;
                if (nNeighbors == 1000) 
                {
                    break; 
                }
                fscanf(fp, "%u", &v1_next);
                fscanf(fp, "%u", &v2_next); 
            }
        }
    }

}

void append(linkedNodeList* pLinkedList, unsigned int node)
{
    //make new node with the intention that it's going to be the new tail
    linkedNode* pNewNode = (linkedNode*)malloc(sizeof(linkedNode));
    pNewNode->node = node; 
    pNewNode->pNextLinkedNode = NULL;
    pNewNode->pPrevLinkedNode = pLinkedList->pTail;

    //set next node of current tail to new node
    (pLinkedList->pTail)->pNextLinkedNode = pNewNode; 

    //new tail becomes new node
    pLinkedList->pTail = pNewNode; 

    //lastly, set old tail's next node to point to new tail
    (pLinkedList->pTail->pPrevLinkedNode)->pNextLinkedNode = pLinkedList->pTail;
}

Judging by the screenshots, and assuming you are on a 64 bit system (a pointer being 8 bytes wide), the pointer pNeighborList links to the start of the list, while pLook links to the pNeighbors attribute of a neighborList element at index 5 :

// assuming sizeof(neighborList) == 4 (int) + 8 (pointer) = 12 bytes

neighborList* pNeighborList = new neighborList[10];
// pNeighborList points to the start of the list, 0x00107a28

// pNeighborList[5] is at address 0x00107a64 (start + 5 * sizeof(neighborList)
// .pNeighbors is offset 4 more bytes (sizeof(unsigned int)) = 0x00107a68

int curNode = 5;
unsigned int* pLook = (pNeighborList[curNode]).pNeighbors;
// pLook points to pNeighbors of the element at index 5, 0x00107a68

When you hover the pointer pNeighborList in Visual Studio, it shows you the pointer (which points to the start of the list), not the full value ( (pNeighborList[curNode]).pNeighbors ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM