带地址的数组

时间:2018-03-09 00:50:33

标签: c arrays pointers bigint

我的代码有问题。我试图实现大整数(比正常大)并且一切顺利。

我选择将它们表示为动态数组。因此,该函数接收一个指针用于短路(使用更少的内存;我可以使用使用1个字节的char,但是很短)并将其设置为动态数组。

在我的主函数上,我有一个数组(短指针),它将具有各种数字(数组)的地址。问题是当我尝试比较当前指针上的数字和数组上的另一个数字时。每当我尝试将该地址分配给指针时,为了进行比较,我会收到编译器的警告:

cast to pointer from integer of different size [-Wint-to-pointer-cast]

我正在尝试分配地址的指针也是一个简短的指针。 尝试:

short *p = arr[0];

short *p = (void *) arr[0];

short *p = (short *) arr[0];

@edit

数组定义为short *arr[SIZE];

因为这是一个警告,程序已经编译,但是当尝试运行它时,我得到Segmentation fault(core dumped)错误,正如预期的那样。

什么是最佳解决方案?

@edit 2:

以下是代码:

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

#define SIZE 10000

int isInArr(short *p, short **arr, int length){
    int i;

    for(i = 0; i < length; i++){
        if(equalBig(arr[i], p)){
            return 1;
        }
    }

    return 0;
}

void freeMem(short **arr, int length){
    int i;

    for(i = 0; i < length; i++){
        free(arr[i]);
    }
}

int main(){
    short *p, *numbers[SIZE] = { NULL };
    int a, b, count = 0;

    p = malloc(sizeof(short)*BIG_INT);

    for(a = 2; a <= 100; a++){
        for(b = 2; b <= 100; b++){
            powerBig(p, a, b);

            if(!isInArr(p, numbers, count)){
                numbers[count] = p;
                createBig(&p);
                count++;
            }else{
                clearBig(p);
            }
        }
    }

    printf("%d\n", count);

    freeMem(numbers, count);

    return 0;
}

bigint.c:

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


/* Type Big Integer */

void createBig(short **pointer){ /* Constructor */
    *pointer = malloc(sizeof(short)*BIG_INT);

    clearBig(*pointer);

    **pointer = STOP;
}

void clearBig(short *pointer){ /* Put 0's on ALL places of the array */
    int i;

    for(i = 0; i < BIG_INT; i++){
        *(pointer+i) = 0;
    }
}

void powerBig(short *p, int a, int b){ /* Operation - power */
    int i = 0, j, digit = 0, rem;
    short *tmp = malloc(sizeof(short)*BIG_INT); /* Variable for temporary allocation of array during product */
    short base[4]; /* Variable for base */
    short *q = base;

    while(a != 0){ /* Put a in an array */
        *(p + i) = a % 10;
        *(q + i) = a % 10;
        a = a / 10;
        i++;
    }

    *(p + i) = STOP;
    *(q + i) = STOP;

    for(i = 1; i < b; i++){
        digit = 0;
        clearBig(tmp);
        while(*(q + digit) != STOP){
            rem = 0;
            j = 0;

            while(*(p + j) != STOP){
                rem += (*(p + j)) * (*(q + digit));
                rem += *(tmp + j + digit);
                *(tmp + j + digit) = rem % 10;
                rem /= 10;
                j++;
            }

            if(rem != 0){
                *(tmp + j + digit) = rem % 10;
                j++;
            }

            *(tmp + j + digit) = STOP;

            digit++;
        }
        copyBig(tmp, p); /* Update the p array */
    }
    free(tmp);
}

void copyBig(short *orig, short *dest){ /* Move big integer to another array */
    int i;
    for(i = 0; *(orig+i) != STOP; i++){
        *(dest+i) = *(orig+i);
    }
    *(dest+i) = STOP;
}

int equalBig(short *p, short *q){
    int i = 0;

    if(p == NULL || q == NULL){
        return 0;
    }

    while(*(q + i) != STOP && *(p + i) != STOP){
        if(*(p + i) != *(q + i)){
            return 0;
        }
        i++;
    }

    return (*(q + i) ==  *(p + i)) ? 1 : 0;
}

Valgrind输出:

--20748-- REDIR: 0x401cfd0 (ld-linux-x86-64.so.2:strlen) redirected to 0x3809e181 (???)
--20748-- Reading syms from /usr/lib/valgrind/vgpreload_core-amd64-linux.so
--20748--   Considering /usr/lib/valgrind/vgpreload_core-amd64-linux.so ..
--20748--   .. CRC mismatch (computed 2567ccf6 wanted 49420590)
--20748--    object doesn't have a symbol table
--20748-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
--20748--   Considering /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so ..
--20748--   .. CRC mismatch (computed 0e27c9a8 wanted ac585421)
--20748--    object doesn't have a symbol table
==20748== WARNING: new redirection conflicts with existing -- ignoring it
--20748--     old: 0x0401cfd0 (strlen              ) R-> (0000.0) 0x3809e181 ???
--20748--     new: 0x0401cfd0 (strlen              ) R-> (2007.0) 0x04c31020 strlen
--20748-- REDIR: 0x401b920 (ld-linux-x86-64.so.2:index) redirected to 0x4c30bc0 (index)
--20748-- REDIR: 0x401bb40 (ld-linux-x86-64.so.2:strcmp) redirected to 0x4c320d0 (strcmp)
--20748-- REDIR: 0x401dd30 (ld-linux-x86-64.so.2:mempcpy) redirected to 0x4c35270 (mempcpy)
--20748-- Reading syms from /lib/x86_64-linux-gnu/libc-2.23.so
--20748--   Considering /lib/x86_64-linux-gnu/libc-2.23.so ..
--20748--   .. CRC mismatch (computed 7a8ee3e4 wanted a5190ac4)
--20748--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/libc-2.23.so ..
--20748--   .. CRC is valid
--20748-- REDIR: 0x4ec9a00 (libc.so.6:strcasecmp) redirected to 0x4a286f0 (_vgnU_ifunc_wrapper)
--20748-- REDIR: 0x4ec5280 (libc.so.6:strcspn) redirected to 0x4a286f0 (_vgnU_ifunc_wrapper)
--20748-- REDIR: 0x4ecbcf0 (libc.so.6:strncasecmp) redirected to 0x4a286f0 (_vgnU_ifunc_wrapper)
--20748-- REDIR: 0x4ec76f0 (libc.so.6:strpbrk) redirected to 0x4a286f0 (_vgnU_ifunc_wrapper)
--20748-- REDIR: 0x4ec7a80 (libc.so.6:strspn) redirected to 0x4a286f0 (_vgnU_ifunc_wrapper)
--20748-- REDIR: 0x4ec914b (libc.so.6:memcpy@GLIBC_2.2.5) redirected to 0x4a286f0 (_vgnU_ifunc_wrapper)
--20748-- REDIR: 0x4ec7400 (libc.so.6:rindex) redirected to 0x4c308a0 (rindex)
--20748-- REDIR: 0x4ec91b0 (libc.so.6:memset) redirected to 0x4a286f0 (_vgnU_ifunc_wrapper)
--20748-- REDIR: 0x4fac970 (libc.so.6:__memset_avx2) redirected to 0x4c344c0 (memset)
--20748-- REDIR: 0x4ebe130 (libc.so.6:malloc) redirected to 0x4c2db20 (malloc)
--20748-- REDIR: 0x4ebe4f0 (libc.so.6:free) redirected to 0x4c2ed80 (free)
==20748== Invalid write of size 2
==20748==    at 0x400B54: powerBig (bigint.c:60)
==20748==    by 0x400794: main (20.c:35)
==20748==  Address 0x5ae1032 is 0 bytes after a block of size 402 alloc'd
==20748==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20748==    by 0x400913: powerBig (bigint.c:26)
==20748==    by 0x400794: main (20.c:35)
==20748== 
==20748== Invalid read of size 2
==20748==    at 0x400C0F: copyBig (bigint.c:71)
==20748==    by 0x400B8C: powerBig (bigint.c:64)
==20748==    by 0x400794: main (20.c:35)
==20748==  Address 0x5ae1032 is 0 bytes after a block of size 402 alloc'd
==20748==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20748==    by 0x400913: powerBig (bigint.c:26)
==20748==    by 0x400794: main (20.c:35)
==20748== 
==20748== Invalid write of size 2
==20748==    at 0x400C28: copyBig (bigint.c:74)
==20748==    by 0x400B8C: powerBig (bigint.c:64)
==20748==    by 0x400794: main (20.c:35)
==20748==  Address 0x5ae0e52 is 0 bytes after a block of size 402 alloc'd
==20748==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20748==    by 0x40087C: createBig (bigint.c:9)
==20748==    by 0x4007DD: main (20.c:39)
==20748== 
==20748== Invalid read of size 2
==20748==    at 0x400AE2: powerBig (bigint.c:47)
==20748==    by 0x400794: main (20.c:35)
==20748==  Address 0x5ae1212 is 0 bytes after a block of size 402 alloc'd
==20748==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20748==    by 0x40087C: createBig (bigint.c:9)
==20748==    by 0x4007DD: main (20.c:39)
==20748== 
==20748== Invalid read of size 2
==20748==    at 0x400A6A: powerBig (bigint.c:49)
==20748==    by 0x400794: main (20.c:35)
==20748==  Address 0x5ae13f2 is 0 bytes after a block of size 402 alloc'd
==20748==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20748==    by 0x400913: powerBig (bigint.c:26)
==20748==    by 0x400794: main (20.c:35)
==20748== 
==20748== Invalid write of size 2
==20748==    at 0x400AB0: powerBig (bigint.c:50)
==20748==    by 0x400794: main (20.c:35)
==20748==  Address 0x5ae13f2 is 0 bytes after a block of size 402 alloc'd
==20748==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20748==    by 0x400913: powerBig (bigint.c:26)
==20748==    by 0x400794: main (20.c:35)
==20748== 
==20748== Invalid write of size 2
==20748==    at 0x400B34: powerBig (bigint.c:56)
==20748==    by 0x400794: main (20.c:35)
==20748==  Address 0x5ae13f4 is 2 bytes after a block of size 402 alloc'd
==20748==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20748==    by 0x400913: powerBig (bigint.c:26)
==20748==    by 0x400794: main (20.c:35)
==20748== 
==20748== Invalid read of size 2
==20748==    at 0x400BF5: copyBig (bigint.c:72)
==20748==    by 0x400B8C: powerBig (bigint.c:64)
==20748==    by 0x400794: main (20.c:35)
==20748==  Address 0x5ae13f2 is 0 bytes after a block of size 402 alloc'd
==20748==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20748==    by 0x400913: powerBig (bigint.c:26)
==20748==    by 0x400794: main (20.c:35)
==20748== 
==20748== Invalid write of size 2
==20748==    at 0x400BF8: copyBig (bigint.c:72)
==20748==    by 0x400B8C: powerBig (bigint.c:64)
==20748==    by 0x400794: main (20.c:35)
==20748==  Address 0x5ae1212 is 0 bytes after a block of size 402 alloc'd
==20748==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20748==    by 0x40087C: createBig (bigint.c:9)
==20748==    by 0x4007DD: main (20.c:39)
==20748== 
==20748== Invalid read of size 2
==20748==    at 0x400A31: powerBig (bigint.c:48)
==20748==    by 0x400794: main (20.c:35)
==20748==  Address 0x5ae15d2 is 0 bytes after a block of size 402 alloc'd
==20748==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20748==    by 0x40087C: createBig (bigint.c:9)
==20748==    by 0x4007DD: main (20.c:39)
==20748== 
--20748-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--20748-- si_code=1;  Faulting address: 0x6112E58;  sp: 0x808ca9e30

valgrind: the 'impossible' happened:
   Killed by fatal signal

host stacktrace:
==20748==    at 0x38091C12: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==20748==    by 0x38050E84: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==20748==    by 0x38051056: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==20748==    by 0x380D4F7B: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==20748==    by 0x380E3946: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable (lwpid 20748)
==20748==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20748==    by 0x40087C: createBig (bigint.c:9)
==20748==    by 0x4007DD: main (20.c:39)

1 个答案:

答案 0 :(得分:0)

如果我理解正确,isInArr会检查p的内容是否已在numbers中。那你有 将指针传递给numbers,因为您必须更改isInArr函数 到:

int isInArr(short *p, short **arr, int length){
    int i;

    if(length >= SIZE)
        length = SIZE; // checking that you don't access `arr` out of bounds

    for(i = 0; i < length; i++){
        if(equalBig(arr[i], p)){
            return 1;
        }
    }

    return 0;
}

并在main中称之为:

if(!isInArr(p, numbers, count)){

因为你想搜索整个numbers数组。我也愿意 像这样声明numbers

short *numbers[SIZE] = { NULL };

以便所有指针都以NULL初始化,在equalBig中您可以添加 额外检查if(p == NULL || q == NULL) return 0;以防范NULL 指针。

修改

  

OP在评论中写道

     

输出是:   20.c: In function ‘isInArr’: 20.c:11:15: warning: passing argument 1 of ‘equalBig’ makes pointer from integer without a cast [-Wint-conversion] if(equalBig(arr[i], p)){ ^ In file included from 20.c:3:0: bigint.h:8:5: note: expected ‘short int ’ but argument is of type ‘short int’ int equalBig(short *p, short *q); / Compare */ ^

我猜你在代码的某个地方仍然有一个小错误,一些变量 仍然是错误的类型。

我可以编译并运行此代码(具有我的修复程序)而没有问题:

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

#define SIZE 10
#define STOP 99

int equalBig(short *p, short *q){
    int i = 0;

    while(*(q + i) != STOP && *(p + i) != STOP){
        if(*(p + i) != *(q + i)){
            return 0;
        }
        i++;
    }

    return (*(q + i) ==  *(p + i)) ? 1 : 0;
}

int isInArr(short *p, short **arr, int length){
    int i;

    if(length >= SIZE)
        length = SIZE; // checking that you don't access `arr` out of bounds

    for(i = 0; i < length; i++){
        if(equalBig(arr[i], p)){
            return 1;
        }
    }

    return 0;
}

int main(void)
{
    short *p, *numbers[SIZE] = { NULL };

    numbers[0] = calloc(10, sizeof *numbers[0]);
    numbers[1] = calloc(10, sizeof *numbers[1]);
    p = calloc(10, sizeof *p);

    numbers[0][3] = STOP;
    numbers[1][4] = STOP;
    p[4] = STOP;

    printf("isInArr: %d\n", isInArr(p, numbers, 2));

    free(numbers[0]);
    free(numbers[1]);
    free(p);

    return 0;
}
$ gcc a.c -oa -g -Wall
$ valgrind ./a 
==10955== Memcheck, a memory error detector
==10955== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==10955== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==10955== Command: ./a
==10955== 
isInArr: 1
==10955== 
==10955== HEAP SUMMARY:
==10955==     in use at exit: 0 bytes in 0 blocks
==10955==   total heap usage: 4 allocs, 4 frees, 1,084 bytes allocated
==10955== 
==10955== All heap blocks were freed -- no leaks are possible
==10955== 
==10955== For counts of detected and suppressed errors, rerun with: -v
==10955== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)