C动态数组内存分配,填充和排序

时间:2021-08-27 07:43:49

I am creating four functions:

我正在创建四个函数:

  1. Allocate memory to an array
  2. 将内存分配给数组
  3. Generate random chars an fill the array
  4. 生成随机字符填充数组
  5. Sort the array into ascending order
  6. 按升序对数组进行排序
  7. Print the sorted array
  8. 打印排序的数组

Like you will see in the code, I use a printf to see the generated chars.
The problem is, that the sorting function is not working right and I can't understand where is the problem (I get an output where the characters aren't sorted like they should be).

就像你将在代码中看到的那样,我使用printf来查看生成的字符。问题是,排序功能不正常,我无法理解问题出在哪里(我得到一个输出,其中字符没有像他们应该那样排序)。

Can someone please tell me what I'm doing wrong? Any other tips on how I can improve all the code would be welcome as well.

有人可以告诉我我做错了什么吗?关于如何改进所有代码的任何其他提示也将受到欢迎。

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

int size = 20;
char* pArrChar1;
void allocate(char**);
void fill(char*);
void sort(char*);
void printArr(char*);

void main() {

    allocate(&pArrChar1);
    fill(pArrChar1);
    sort(pArrChar1);
    printArr(pArrChar1);

   system("pause");
}

void allocate(char** p_char) {
    *p_char = (char*)malloc(size*sizeof(char));
}

void fill(char* p_char) {
    int max = 90 ;
    int min = 65;
    for (int i = 0; i < size; i++) {
        p_char[i]= (char)(rand() % (min + 1 - max) + min);
        printf("%c ", p_char[i]);
    }
    printf("\n\n");
}

void sort(char* p_char) {
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size - 1; j++) {
            if (*(p_char + j) > *(p_char + j + 1)) {
                char tmp = *(p_char + j);
                *(p_char + j) = *(p_char + j + 1);
                *(p_char + j + 1) = tmp;
            }
        }
    }
}

void printArr(char* p_char) {
    for (int i = 0; i < size; i++)
        printf("%c ", p_char[i]);
   printf("\n\n");
}

4 个解决方案

#1


1  

You have an implementation error on line 38. This verbose output below shows what line it faulted on. The "ASan" tool claims you have a heap buffer overflow.

第38行有一个实现错误。下面的详细输出显示了它出错的行。 “ASan”工具声称您有堆缓冲区溢出。

When i is 19, you dereference p_char[20], this is beyond the end of the allocation.

当我19岁时,你解除引用p_char [20],这超出了分配的结束。

$ clang -fsanitize=address -g -Wall sorter.c 
sorter.c:11:1: warning: return type of 'main' is not 'int' [-Wmain-return-type]
void main() {
^
sorter.c:11:1: note: change return type to 'int'
void main() {
^~~~
int
1 warning generated.
$ ./a.out 
H W J T R H K M J N C T C T L W M S E Q 

=================================================================
==7176==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000eff4 at pc 0x0000004cd8af bp 0x7fff8db88420 sp 0x7fff8db88418
READ of size 1 at 0x60300000eff4 thread T0
    #0 0x4cd8ae in sort /home/brian/src/so/sorter.c:38:33
    #1 0x4cd5e4 in main /home/brian/src/so/sorter.c:15:5
    #2 0x7fbeb021da3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f)
    #3 0x417508 in _start (/home/brian/src/so/a.out+0x417508)

0x60300000eff4 is located 0 bytes to the right of 20-byte region [0x60300000efe0,0x60300000eff4)
allocated by thread T0 here:
    #0 0x4a626b in __interceptor_malloc /home/development/llvm/3.7.0/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:40:3
    #1 0x4cd65c in allocate /home/brian/src/so/sorter.c:22:22
    #2 0x4cd576 in main /home/brian/src/so/sorter.c:13:5
    #3 0x7fbeb021da3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/brian/src/so/sorter.c:38:33 in sort
Shadow bytes around the buggy address:
  0x0c067fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c067fff9df0: fa fa fa fa fa fa fa fa fa fa fa fa 00 00[04]fa
  0x0c067fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9e40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==7176==ABORTING

#2


1  

Here I updated the sort function with the following one;

在这里,我使用以下函数更新了sort函数;

/* new sort */
void sort2(char* p_char) {
    counter = 0;
    for (int i = 0; i < size - 1; i++) {
        for (int j = i + 1; j < size; j++) {
            if (*(p_char + i) > *(p_char + j)) {
                char tmp = *(p_char + i);
                *(p_char + i) = *(p_char + j);
                *(p_char + j) = tmp;

                counter++;
            }
        }
    }
    printf("Sort2 process # : %d\n", counter);
}

And using this updated sort, improves the process number for finding the solution, the output as below for 50,000 random chars;

并使用此更新的排序,改进了查找解决方案的流程数,输出如下为50,000个随机字符;

D:\SOF>gcc main.c -Wall -Wextra -pedantic -std=c11 -o main

D:\SOF>main
Sort  process # : 598810451
Sort2 process # : 574789

Please checkout the test code down below;

请查看下面的测试代码;

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

#define MAX_SIZE 50000

int counter = 0;
int size = MAX_SIZE;
char* pArrChar1;
void allocate(char**);
void fill(char*);
void sort(char*);
void sort2(char* p_char); /* updated sort */
void printArr(char*);

int main() {

    allocate(&pArrChar1);
    fill(pArrChar1);
    sort(pArrChar1);
    //printArr(pArrChar1);

    allocate(&pArrChar1);
    fill(pArrChar1);
    sort2(pArrChar1);

    system("pause");

    return 0;
}

void allocate(char** p_char) {
    *p_char = (char*)malloc(size*sizeof(char));
}

void fill(char* p_char) {
    int max = 90 ;
    int min = 65;
    for (int i = 0; i < size; i++) {
        p_char[i]= (char)(rand() % (min + 1 - max) + min);
        //printf("%c ", p_char[i]);
    }
    //printf("\n\n");
}

void sort(char* p_char) {
    counter = 0;
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size - 1; j++) {
            if (*(p_char + j) > *(p_char + j + 1)) {
                char tmp = *(p_char + j);
                *(p_char + j) = *(p_char + j + 1);
                *(p_char + j + 1) = tmp;

                counter++;
            }
        }
    }
    printf("Sort  process # : %d\n", counter);
}

/* new sort */
void sort2(char* p_char) {
    counter = 0;
    for (int i = 0; i < size - 1; i++) {
        for (int j = i + 1; j < size; j++) {
            if (*(p_char + i) > *(p_char + j)) {
                char tmp = *(p_char + i);
                *(p_char + i) = *(p_char + j);
                *(p_char + j) = tmp;

                counter++;
            }
        }
    }
    printf("Sort2 process # : %d\n", counter);
}

void printArr(char* p_char) {
    for (int i = 0; i < size; i++)
        printf("%c ", p_char[i]);
    printf("\n\n");
}

Hope that it helps!

希望它有所帮助!

#3


0  

In your code, you have:

在您的代码中,您有:

for (int i = 0; i < size; i++) {
    for (int j = 0; j < size - 1; j++) {
        if (*(p_char + i) > *(p_char + i + 1)) {

When i is equal to size - 1, you're accessing out of bounds.

当我等于大小-1时,你正在访问越界。

Change the loop limits:

更改循环限制:

for (int i = 0; i < size - 1; i++) {
    for (int j = 0; j < size; j++) {
        if (*(p_char + i) > *(p_char + i + 1)) {

This at least avoids the out of bounds array access. It is surprising that you aren't using i and j as subscripts; you seem to repeat the same comparison a lot as written.

这至少避免了越界数组访问。令人惊讶的是你没有使用i和j作为下标;你似乎重复了相同的比较。

#4


0  

the sort function had an error, this is the correct one

sort函数有错误,这是正确的

void sort(char* p_char) {
for (int i = 0; i < size; i++) {
    for (int j = 0; j < size - 1; j++) {
        if (*(p_char+j) > *(p_char + j + 1)) {
            char tmp = *(p_char + j);
            *(p_char + j) = *(p_char + j + 1);
            *(p_char + j + 1) = tmp;
        }
      }
   }
}

#1


1  

You have an implementation error on line 38. This verbose output below shows what line it faulted on. The "ASan" tool claims you have a heap buffer overflow.

第38行有一个实现错误。下面的详细输出显示了它出错的行。 “ASan”工具声称您有堆缓冲区溢出。

When i is 19, you dereference p_char[20], this is beyond the end of the allocation.

当我19岁时,你解除引用p_char [20],这超出了分配的结束。

$ clang -fsanitize=address -g -Wall sorter.c 
sorter.c:11:1: warning: return type of 'main' is not 'int' [-Wmain-return-type]
void main() {
^
sorter.c:11:1: note: change return type to 'int'
void main() {
^~~~
int
1 warning generated.
$ ./a.out 
H W J T R H K M J N C T C T L W M S E Q 

=================================================================
==7176==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000eff4 at pc 0x0000004cd8af bp 0x7fff8db88420 sp 0x7fff8db88418
READ of size 1 at 0x60300000eff4 thread T0
    #0 0x4cd8ae in sort /home/brian/src/so/sorter.c:38:33
    #1 0x4cd5e4 in main /home/brian/src/so/sorter.c:15:5
    #2 0x7fbeb021da3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f)
    #3 0x417508 in _start (/home/brian/src/so/a.out+0x417508)

0x60300000eff4 is located 0 bytes to the right of 20-byte region [0x60300000efe0,0x60300000eff4)
allocated by thread T0 here:
    #0 0x4a626b in __interceptor_malloc /home/development/llvm/3.7.0/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:40:3
    #1 0x4cd65c in allocate /home/brian/src/so/sorter.c:22:22
    #2 0x4cd576 in main /home/brian/src/so/sorter.c:13:5
    #3 0x7fbeb021da3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/brian/src/so/sorter.c:38:33 in sort
Shadow bytes around the buggy address:
  0x0c067fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c067fff9df0: fa fa fa fa fa fa fa fa fa fa fa fa 00 00[04]fa
  0x0c067fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9e40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==7176==ABORTING

#2


1  

Here I updated the sort function with the following one;

在这里,我使用以下函数更新了sort函数;

/* new sort */
void sort2(char* p_char) {
    counter = 0;
    for (int i = 0; i < size - 1; i++) {
        for (int j = i + 1; j < size; j++) {
            if (*(p_char + i) > *(p_char + j)) {
                char tmp = *(p_char + i);
                *(p_char + i) = *(p_char + j);
                *(p_char + j) = tmp;

                counter++;
            }
        }
    }
    printf("Sort2 process # : %d\n", counter);
}

And using this updated sort, improves the process number for finding the solution, the output as below for 50,000 random chars;

并使用此更新的排序,改进了查找解决方案的流程数,输出如下为50,000个随机字符;

D:\SOF>gcc main.c -Wall -Wextra -pedantic -std=c11 -o main

D:\SOF>main
Sort  process # : 598810451
Sort2 process # : 574789

Please checkout the test code down below;

请查看下面的测试代码;

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

#define MAX_SIZE 50000

int counter = 0;
int size = MAX_SIZE;
char* pArrChar1;
void allocate(char**);
void fill(char*);
void sort(char*);
void sort2(char* p_char); /* updated sort */
void printArr(char*);

int main() {

    allocate(&pArrChar1);
    fill(pArrChar1);
    sort(pArrChar1);
    //printArr(pArrChar1);

    allocate(&pArrChar1);
    fill(pArrChar1);
    sort2(pArrChar1);

    system("pause");

    return 0;
}

void allocate(char** p_char) {
    *p_char = (char*)malloc(size*sizeof(char));
}

void fill(char* p_char) {
    int max = 90 ;
    int min = 65;
    for (int i = 0; i < size; i++) {
        p_char[i]= (char)(rand() % (min + 1 - max) + min);
        //printf("%c ", p_char[i]);
    }
    //printf("\n\n");
}

void sort(char* p_char) {
    counter = 0;
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size - 1; j++) {
            if (*(p_char + j) > *(p_char + j + 1)) {
                char tmp = *(p_char + j);
                *(p_char + j) = *(p_char + j + 1);
                *(p_char + j + 1) = tmp;

                counter++;
            }
        }
    }
    printf("Sort  process # : %d\n", counter);
}

/* new sort */
void sort2(char* p_char) {
    counter = 0;
    for (int i = 0; i < size - 1; i++) {
        for (int j = i + 1; j < size; j++) {
            if (*(p_char + i) > *(p_char + j)) {
                char tmp = *(p_char + i);
                *(p_char + i) = *(p_char + j);
                *(p_char + j) = tmp;

                counter++;
            }
        }
    }
    printf("Sort2 process # : %d\n", counter);
}

void printArr(char* p_char) {
    for (int i = 0; i < size; i++)
        printf("%c ", p_char[i]);
    printf("\n\n");
}

Hope that it helps!

希望它有所帮助!

#3


0  

In your code, you have:

在您的代码中,您有:

for (int i = 0; i < size; i++) {
    for (int j = 0; j < size - 1; j++) {
        if (*(p_char + i) > *(p_char + i + 1)) {

When i is equal to size - 1, you're accessing out of bounds.

当我等于大小-1时,你正在访问越界。

Change the loop limits:

更改循环限制:

for (int i = 0; i < size - 1; i++) {
    for (int j = 0; j < size; j++) {
        if (*(p_char + i) > *(p_char + i + 1)) {

This at least avoids the out of bounds array access. It is surprising that you aren't using i and j as subscripts; you seem to repeat the same comparison a lot as written.

这至少避免了越界数组访问。令人惊讶的是你没有使用i和j作为下标;你似乎重复了相同的比较。

#4


0  

the sort function had an error, this is the correct one

sort函数有错误,这是正确的

void sort(char* p_char) {
for (int i = 0; i < size; i++) {
    for (int j = 0; j < size - 1; j++) {
        if (*(p_char+j) > *(p_char + j + 1)) {
            char tmp = *(p_char + j);
            *(p_char + j) = *(p_char + j + 1);
            *(p_char + j + 1) = tmp;
        }
      }
   }
}