指针/动态内存分配功能错误(Xcode to Linux)

时间:2018-03-04 18:58:09

标签: c++ linux xcode function pointers

我刚刚学习了类中的指针,并且有一个赋值,程序允许用户通过测试四个函数来实现指针和动态内存分配。

我遇到问题的唯一地方是最后一个函数subArray。这应该只显示由起始索引和长度值设置指定的数组的某个部分。

这个程序在Xcode上工作正常,给出正确的输出并返回0.这是Xcode上的输出:

Testing isSorted: 

Test data for array 1: 1 2 3 4 5 6 7 8 
Expected result: true 
Actual result: true
Test data for array 2: 8 7 6 5 4 3 2 1 
Expected result: false
Actual result: false
Test data for array 3: 1 2 3 5 4 6 7 8 
Expected result: false
Actual result: false


Testing chain for 15.46 inches: 

Expected result: 15.46 feet: 4 inches: 5
Actual result: 15.46 feet: 4 inches: 5


Testing grow: 

Test data: 1 2 3 4 5 6 7 8 9 
Expected result: 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 
Actual result: 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 


Testing subArray: 

Test data: 1 2 3 4 5 6 7 8 9 
Start: 5 Length: 4
Expected result: 6 7 8 9 
Actual result: 6 7 8 9 
Program ended with exit code: 0

但是,我必须在Linux上编译以获得完全的功劳,并且在Linux上运行代码时会收到以下问题:

Error in `./exe': free(): invalid pointer: 0x0000000000678060 ***

输出与Xcode完全相同,除了最后的"实际结果:"测试subArray函数的行。

Testing subArray: 

Test data: 1 2 3 4 5 6 7 8 9 
Start: 5 Length: 4
Expected result: 6 7 8 9 
*** Error in `./run': free(): invalid pointer: 0x0000000000678060 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x7c619)[0x7f1da7cd3619]
/lib64/libc.so.6(+0x7d1bb)[0x7f1da7cd41bb]
/lib64/libc.so.6(+0x7dba5)[0x7f1da7cd4ba5]
/lib64/libc.so.6(__libc_malloc+0x4c)[0x7f1da7cd710c]
/lib64/libstdc++.so.6(_Znwm+0x1d)[0x7f1da85911bd]
/lib64/libstdc++.so.6(_Znam+0x9)[0x7f1da85912b9]
./run[0x401376]
./run[0x401327]
./run[0x401097]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f1da7c78c05]
./run[0x4009c9]
======= Memory map: ========
00400000-00402000 r-xp 00000000 00:2e 9715713                            /home/Students/klw231/run
00601000-00602000 r--p 00001000 00:2e 9715713                            /home/Students/klw231/run
00602000-00603000 rw-p 00002000 00:2e 9715713                            /home/Students/klw231/run
00678000-006bb000 rw-p 00000000 00:00 0                                  [heap]
7f1da0000000-7f1da0021000 rw-p 00000000 00:00 0 
7f1da0021000-7f1da4000000 ---p 00000000 00:00 0 
7f1da7c57000-7f1da7e0f000 r-xp 00000000 fd:00 67288141                   /usr/lib64/libc-2.17.so
7f1da7e0f000-7f1da800f000 ---p 001b8000 fd:00 67288141                   /usr/lib64/libc-2.17.so
7f1da800f000-7f1da8013000 r--p 001b8000 fd:00 67288141                   /usr/lib64/libc-2.17.so
7f1da8013000-7f1da8015000 rw-p 001bc000 fd:00 67288141                   /usr/lib64/libc-2.17.so
7f1da8015000-7f1da801a000 rw-p 00000000 00:00 0 
7f1da801a000-7f1da802f000 r-xp 00000000 fd:00 67161030                   /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f1da802f000-7f1da822e000 ---p 00015000 fd:00 67161030                   /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f1da822e000-7f1da822f000 r--p 00014000 fd:00 67161030                   /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f1da822f000-7f1da8230000 rw-p 00015000 fd:00 67161030                   /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f1da8230000-7f1da8331000 r-xp 00000000 fd:00 67657412                   /usr/lib64/libm-2.17.so
7f1da8331000-7f1da8530000 ---p 00101000 fd:00 67657412                   /usr/lib64/libm-2.17.so
7f1da8530000-7f1da8531000 r--p 00100000 fd:00 67657412                   /usr/lib64/libm-2.17.so
7f1da8531000-7f1da8532000 rw-p 00101000 fd:00 67657412                   /usr/lib64/libm-2.17.so
7f1da8532000-7f1da861b000 r-xp 00000000 fd:00 67150761                   /usr/lib64/libstdc++.so.6.0.19
7f1da861b000-7f1da881b000 ---p 000e9000 fd:00 67150761                   /usr/lib64/libstdc++.so.6.0.19
7f1da881b000-7f1da8823000 r--p 000e9000 fd:00 67150761                   /usr/lib64/libstdc++.so.6.0.19
7f1da8823000-7f1da8825000 rw-p 000f1000 fd:00 67150761                   /usr/lib64/libstdc++.so.6.0.19
7f1da8825000-7f1da883a000 rw-p 00000000 00:00 0 
7f1da883a000-7f1da885b000 r-xp 00000000 fd:00 67150948                   /usr/lib64/ld-2.17.so
7f1da8a47000-7f1da8a4c000 rw-p 00000000 00:00 0 
7f1da8a58000-7f1da8a5b000 rw-p 00000000 00:00 0 
7f1da8a5b000-7f1da8a5c000 r--p 00021000 fd:00 67150948                   /usr/lib64/ld-2.17.so
7f1da8a5c000-7f1da8a5d000 rw-p 00022000 fd:00 67150948                   /usr/lib64/ld-2.17.so
7f1da8a5d000-7f1da8a5e000 rw-p 00000000 00:00 0 
7ffc48603000-7ffc48624000 rw-p 00000000 00:00 0                          [stack]
7ffc4867b000-7ffc4867d000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Actual result: Aborted

我知道函数中的某个指针必定会出现问题,但我已经尝试了许多可能的解决方案,并希望更好地了解我可以采取哪些措施来解决这个问题。提前谢谢!

#include <iostream>
#include <stdlib.h>

using namespace std;


// Function prototypes

bool isSorted(int *arr, int size);
double chain(int totalInches, int *feet, int *inches);
int *grow(int *arr, int size);
int *subArray(int *arr, int start, int length);
int *duplicateArray(int *arr, int size);
void showArray( int *arr, int size);


int main()
{
int *arr = NULL;      //to dynamically allocate an array


// Test isSorted

 int size = 8;
 int testArray[] = {1, 2, 3, 4, 5, 6, 7, 8};
 cout << endl;
 cout << "Testing isSorted: \n" << endl;
 cout << "Test data for array 1: ";
    showArray(testArray, size);
 cout << "\nExpected result: true " << endl;
 cout << "Actual result: " << boolalpha << isSorted(testArray, size);

 int testArray2[]= {8, 7, 6, 5, 4, 3, 2, 1};
 cout << "\nTest data for array 2: ";
    showArray(testArray2, size);
 cout << "\nExpected result: false" << endl;
 cout << "Actual result: " << boolalpha << isSorted(testArray2, size);

 int testArray3[] = {1, 2, 3, 5, 4, 6, 7, 8};
 cout << "\nTest data for array 3: ";
    showArray(testArray3, size);
 cout << "\nExpected result: false" << endl;
 cout << "Actual result: " << boolalpha << isSorted(testArray3, size);
 cout << endl;


// Test chain

 int totalInches = 53;
 int inches;
 int feet;
 double expected = chain(totalInches, &feet, &inches);

 cout << "\n\nTesting chain for " << expected << " inches: " << endl;
 cout << "\nExpected result: " << expected << " feet: "<< feet << " inches: " << inches << endl;
 cout << "Actual result: " << chain(totalInches, &feet, &inches)
 << " feet: " << feet << " inches: " << inches << "\n" << endl;
 cout << endl;


// Test grow

 int testArray4[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
 size = 9;  // Size is now larger
 cout << "Testing grow: " << endl;
 cout << "\nTest data: ";
    showArray(testArray4, size);
 cout << "\nExpected result: 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 " << endl;
 cout << "Actual result: ";
    showArray(grow(testArray4, size),size*2);
 cout << endl;


// Test subArray

 int start = 5;
 int length = 4;

 cout << "\n\nTesting subArray: " << endl;
 cout << "\nTest data: ";
    showArray(testArray4, size);
 size = length;
 cout << "\nStart: " << start << " " << "Length: " << length << endl;
 cout << "Expected result: 6 7 8 9 " << endl;
 cout << "Actual result: ";

 int *c = subArray(testArray4, start, length);
for(int i=0; i<size; i++)
{
    cout << *(c + i) << " ";
}
 cout << endl;
delete [] c;
c = NULL;

delete arr;      // Releasing dynamically allocated space
arr = NULL;

return 0;
}
//************************************************************************
// bool isSorted: determines whether or not elements in the array are sorted
//
// int *arr: A pointer to a dynamically allocated array
// int size: The number of elements in the array
// returns:  This function returns either a true or false boolean value.
//************************************************************************

bool isSorted(int *arr, int size)
{
    for(int index = 0; index < size - 1; index ++)
    {
        if(*(arr + index) > *(arr + index + 1))
        {
            return false;
        }
    }
    return true;
}


//************************************************************************
// double chain: takes in values from main and performs math operations on them
//
// int totalInches: Adds together feet and inches
// int *feet: A pointer to it's respective value in main
// int *inches: A pointer to it's respective value in main
// returns: This function returns the result as an integer pointer.
//************************************************************************

double chain (int totalInches, int *feet, int *inches)
{

        *feet = totalInches / 12;
        *inches = totalInches % 12;

    return *(feet) * 3.49 + *(inches) * 0.30;
}


//************************************************************************
// int *grow: creates a new array twice the size of the argument array
//
// int *arr: A pointer to a dynamically allocated array
// int size: The number of elements in the array
// returns: This function returns the new array as an integer pointer.
//************************************************************************

int *grow (int *arr, int size)
{
    int *newArray;
    newArray = new int[size*2];      //allocate new array

    for(int i=0; i<(size*2); i+=1)
    {
        *(newArray + i) = *(arr + i / 2);
        *(newArray + i + 1) = *(arr + i / 2);
    }

    return newArray;
}


//************************************************************************
// int *subArray:
//
// int *arr: A pointer to a dynamically allocated array
// int start: Sets the starting element to display
// int length: Sets how long the array segment to display is
// returns: This function returns the result as an integer pointer.
//************************************************************************

int *subArray(int *arr, int start, int length)
{
    int *result = duplicateArray(arr + start, length);

    return result;
}


//************************************************************************
// int *duplicateArray: copies array and returns only selected values
//
// int *arr: A pointer to a dynamically allocated array
// int size: The number of elements in the array
// returns: This function returns the new array as an integer pointer.
//************************************************************************

int *duplicateArray (int *arr, int size)
{

    int *newArray;
    if (size <= 0)         //size must be positive
        return NULL;       //NULL is 0, an invalid address

    newArray = new int [size];  //allocate new array

    for (int index = 0; index < size; index++)
        newArray[index] = arr[index];  //copy to new array

    return newArray;
}


//************************************************************************
// void showArray: displays the contents of the array
//
// int *arr: A pointer to a dynamically allocated array
// int size: The number of elements in the array
// returns: This function is void and does not return a value.
//************************************************************************

void showArray( int *arr, int size)
{
    for(int i=0; i<size; i++)
    {
        cout << *(arr + i) << " ";
    }
    return;
}

1 个答案:

答案 0 :(得分:0)

不幸的是,这项任务是试图教授C ++同时最终教授C的一些突变变体的人之一。你的问题的原因似乎是这段代码:

int *c = subArray(testArray4, start, length);
for(int i=0; i<size; i++)
{
    cout << *(c + i) << " ";
}

返回的数组只有length长度,但迭代器上升到size,所以它走出分配的最后并最终触发未定义的行为。它无效。 “修复”是这样的:

int *c = subArray(testArray4, start, length);
for(int i=0; i<length; i++)
{
    cout << *(c + i) << " ";
}

我能够通过删除许多不属于问题的代码来找到这个问题。当编译器抱怨size未定义时,我知道问题是什么,这是其他测试的值在这里被不适当地使用。这就是为什么保持你的代码尽可能有组织是关键,当你无法清楚地看到事情时,错误可能会蔓延。

更好的方法是为数组定义class以及相关的迭代器以帮助导航它。这不仅不那么杂乱且容易出错,而且作为奖励,它使它与标准库中的现有C ++容器工具完全兼容。你应该继续专业地做这个,知道如何使自己的标准库兼容类是一项非常重要的技能。

我很失望很少有课程能想到这么做。