簡體   English   中英

拋出異常:訪問沖突

[英]Exception Thrown: access violation

此函數反轉指針數組並將其返回到 main。 主要問題是代碼返回一個異常拋出:讀取訪問沖突。 fptr 是 0xCCCCCCCC。

最小描述

什么可能是錯誤的來源?

int* mirror(int* p[], int n) {
    int* ptr,* fptr;
    int swap;
    ptr = p[0];
    fptr = p[n-1];
    while (fptr > ptr) {
        swap = *ptr;
        *ptr = *fptr;
        *fptr = swap;
        ptr++;
        fptr--;
    }
    return *p;
}

這就是問題:

while (fptr > ptr) { ... }

ptr是第一個元素(第一個指針),而fptr是最后一個元素(最后一個指針),當第一個元素小於最后一個元素時,您正在遍歷數組,但這意味着數組中的元素按地址順序插入,我認為這不是..

相反,您應該使用維度 ( n ) 來做到這一點:

int** mirror(int* p[], int n) { // return a pointer to integers pointer, not a pointer to integer
    for(int i = 0; i < n/2 ; i++){ // go through the first half of the array
       int* tmp = p[i];  // and those three lines swap the current and the n - current elements
       p[i] = p[n-i-1];
       p[n] = tmp;
    }
    return p;
}

對於初學者來說,函數的返回類型int *沒有意義。

int* mirror(int* p[], int n) {

最好將該函數聲明為具有返回類型void

如果您有一個int *類型的指針數組,則指向其元素的指針的類型為int **

此外,用戶可以傳遞 0 作為第二個參數。 你應該檢查這個案例。

異常的原因可能是數組包含指向原始數組之外的無效指針。

此外,如果指針數組的形成方式不需要例如第一個指針指向原始數組的第一個元素,那么您的函數將無法工作。

該函數可以定義為

void mirror( int * p[], size_t n ) 
{
    if ( n != 0 )
    {
        for ( int **first = p, **last = p + n; first < --last; ++first )
        {
            int tmp = **first;
            **first = **last;
            **last = tmp;
        }
    }
}

這是一個演示程序

#include <iostream>

void mirror( int * p[], size_t n ) 
{
    if ( n != 0 )
    {
        for ( int **first = p, **last = p + n; first < --last; ++first )
        {
            int tmp = **first;
            **first = **last;
            **last = tmp;
        }
    }
}

int main() 
{
    const size_t N = 5;
    int a[N] = { 10, 30, 30, 40, 50 };
    int * b[N] = { a, a + 1, a + 2, a + 3, a + 4 };

    for ( const auto &item : a )
    {
        std::cout << item << ' ';
    }
    std::cout << '\n';

    mirror( b, N );

    for ( const auto &item : a )
    {
        std::cout << item << ' ';
    }
    std::cout << '\n';

    return 0;
}

程序輸出是

10 30 30 40 50 
50 40 30 30 10

請注意,您可以使用標准函數std::swap而不是“手動”交換元素。

問題是您使用了錯誤的類型。 正確的版本是:

    int **ptr, **fptr;
    int* swap;
    ptr = &p[0];
    fptr = &p[n - 1];

通過這些更改,您的函數可以按預期工作,盡管它返回的內容在大多數情況下無法使用。 要么返回p ( int** ) 要么讓它void

void mirror(int* p[], int n) {
    if(n > 0) {                  // check this or you risk undefined behavior
        int** ptr = &p[0];
        int** fptr = &p[n-1];
        int* swap;
        while(ptr < fptr) {
            swap = *ptr;
            *ptr = *fptr;
            *fptr = swap;
            ptr++;
            fptr--;
        }
    }
}

請注意,已經有一個標准實用程序用於交換兩個名為std::swap值:

void mirror(int* p[], int n) {
    if(n > 0) {
        for(int **ptr = &p[0], **fptr = &p[n - 1]; ptr < fptr; ++ptr, --fptr) {
            std::swap(*ptr, *fptr);
        }
    }
}

最后要注意的是,還有一個標准實用程序用於反轉名為std::reverse的容器中的值,它執行您的mirror函數所做的工作。

代替

mirror(arr, std::size(arr));

std::reverse(std::begin(arr), std::end(arr));

嘗試按如下方式導航您的數組:

void mirror(int* p, int n){
  int* ptr,* fptr;
  int swap;
  ptr = p;
  fptr = p+n-1;
  while (fptr != ptr) {
    swap = *ptr;
    *ptr = *fptr;
    *fptr = swap;
    ptr++;
    fptr--;
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM