我的代码有问题。我试图实现大整数(比正常大)并且一切顺利。
我选择将它们表示为动态数组。因此,该函数接收一个指针用于短路(使用更少的内存;我可以使用使用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)
答案 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)