C++ 指针上的访问冲突
在这段代码中,我试图将十进制数转换为二进制数。(是的,我知道这样一个函数是存在的——我试着重新发明轮子作为练习。)因为我使用一个函数C++ 指针上的访问冲突,c++,pointers,pass-by-reference,C++,Pointers,Pass By Reference,在这段代码中,我试图将十进制数转换为二进制数。(是的,我知道这样一个函数是存在的——我试着重新发明轮子作为练习。)因为我使用一个函数toBinNum()来转换数字,我想通过引用传递一个空数组,然后在数组中存储我的二进制数字,然后返回到main()函数,我将使用数组binNum。这种情况不会发生;我传递指针,初始化它并存储我的二进制数字,但当我返回main()并尝试访问指针时,它失败,发出“指针访问冲突”错误。我假设内存正在被释放,尽管我不知道为什么,因为指针的作用域在main()中,而new关键
toBinNum()
来转换数字,我想通过引用传递一个空数组,然后在数组中存储我的二进制数字,然后返回到main()
函数,我将使用数组binNum
。这种情况不会发生;我传递指针,初始化它并存储我的二进制数字,但当我返回main()
并尝试访问指针时,它失败,发出“指针访问冲突”
错误。我假设内存正在被释放,尽管我不知道为什么,因为指针的作用域在main()
中,而new
关键字是在toBinNum()中创建数组时使用的。为什么这不起作用,我怎样才能修复它
#include <cmath>
#include <iostream>
using namespace std;
void toBinNum(int, int*, int&);
int main(){
int* binNum = nullptr; //binNum will hold the array of binary digits
int binNumSize;
toBinNum(100, binNum, binNumSize);
int numOnes = 0;
for (int j = 0; j < binNumSize; j++){
if (binNum[j] == 1) //ERROR.
numOnes++;
cout << binNum[j];
}
cout << numOnes;
cin.get();
}
/*void toBinNum().
Converts decimal number to binary.
Parameters:
binNum is an int pointer with value NULL, toBinNum() will use this pointer to store an int array of 0s and 1s it generates (each index will hold a binary value).
binNumSize is an int, holds the length of the binNum array for use in other scopes
decNum is an int, it is the decimal number that is to be converted to binary.
*/
void toBinNum(int decNum, int* binNum, int& binNumSize) {
binNumSize = int(log2(decNum)) + 1; //How many digits will binNum be?
binNum = new int[binNumSize];
int factor = pow(2, binNumSize - 1); //What is the largest 2^n that we should start dividing decNum by?
//Find 1s and 0s for binary array
for (int j = 0; factor >= 1; j++){
if (decNum / factor > 0){
binNum[j] = 1; // 1 1 0 0 1
decNum %= factor; //100 36 4 0
}
else
binNum[j] = 0;
factor /= 2; // 64 32 16 8 4 2
}
//Output each index of binNum. Confirmation that this function works.
for (int j = 0; j < binNumSize; j++)
cout << binNum[j] << endl;
}
#包括
#包括
使用名称空间std;
无效toBinNum(int,int*,int&);
int main(){
int*binNum=nullptr;//binNum将保存二进制数字数组
int binnumize;
toBinNum(100,binNum,binnumize);
int numOnes=0;
对于(int j=0;j 不能通过引用传递指针
void toBinNum(int, int* &, int&);
在C语言中,您可以再使用一个间接寻址
void toBinNum(int, int**, int*);
函数声明的问题是,任何未通过引用传递的参数(尽管引用也是函数的局部变量)都是函数的局部变量,在退出函数后会被销毁。局部变量的任何更改都不会影响原始参数
你可以用下面的方法来想象函数调用
void f( int *p );
你可以这样称呼它
int main()
{
int *q = nullptr;
f( q );
//...
那么函数定义可以想象为
void f( /* int *p */ )
{
int *p = q;
p = new int;
//...
如您所见,参数q
没有更改。是局部变量p
获得了一个新值。通过引用传递指针
void toBinNum(int, int* &, int&);
在C语言中,您可以再使用一个间接寻址
void toBinNum(int, int**, int*);
函数声明的问题是,任何未通过引用传递的参数(尽管引用也是函数的局部变量)都是函数的局部变量,在退出函数后会被销毁。局部变量的任何更改都不会影响原始参数
你可以用下面的方法来想象函数调用
void f( int *p );
你可以这样称呼它
int main()
{
int *q = nullptr;
f( q );
//...
那么函数定义可以想象为
void f( /* int *p */ )
{
int *p = q;
p = new int;
//...
正如您所看到的,参数q
没有更改。是局部变量p
获得了一个新值。我知道这个回答不是问题的正确答案(我在问题上面的评论中已经回答了),但我认为这是将数字转换为二进制格式的一个很好的解决方案。不过,它向您展示了在函数调用之外分配资源的想法,而无需使用**
或&*
我使用下面的代码打印整数的二进制转换。在这种代码中,我使用函数iToBin()
将整数转换为字符数组,可以打印或使用任何字符。此函数还使用可选参数-sym
,可用于指定哪些“符号”将插入数组而不是符号“0”和“1”。函数iToBin()
将高位编码到buff
数组的第一个元素中,然后buff[0]
是转换后的数字的高位
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<stdint.h>
using namespace std;
char * iToBin(uint64_t n, char *buff, int len, const char *sym=(const char []){'0','1'});
char * iToBin(uint64_t n,char *buff,int len, const char *sym)
{
uint64_t k=1;
*(buff+ --len)=0;
do {
*(buff+ --len)=(n&k)?sym[1]:sym[0];
k<<=1;
} while(k && len);
return buff;
}
int main(void) {
uint64_t value;
int len=0;
char * buff;
buff=new char[sizeof(value)*8+1];
if (buff==NULL) {
cout << "Not enough memory" << endl;
return 1;
}
do {
cout << "Insert the value to convert: ";
cin >> value;
//len=(log2(value)+1); //number of digit
//len++; // to insert the string0 terminator
//It's better to use this to compute the number of bits!
len=64;
while(!(value & (1ULL<<(len-1))) && len>1) len--;
len++; //to insert string 0 terminator
iToBin(value,buff,len);
int numOnes=0;
for(int i=0;i<len-1;i++) {
if (buff[i]=='1') {
numOnes++;
}
}
cout << buff << " contains " << numOnes << " 1" << endl;
} while(value!=0);
delete buff;
return 0;
}
您可以使用以下代码生成一个代码,其中位由0和1数值表示:
sym[0]=0;sym[1]=1;
但是缓冲区结果作为以C 0结尾的字符串将不会有用!我知道这个回答不是对这个问题的正确回答(我已经在问题上面的评论中回答了),但我认为这是将数字转换为二进制格式的一个很好的解决方案。不过,它向您展示了在函数调用之外分配资源的想法,而无需使用**
或&*
我使用下面的代码打印整数的二进制转换。在这种代码中,我使用函数iToBin()
将整数转换为字符数组,可以打印或使用任何字符。此函数还使用可选参数-sym
,可用于指定哪些“符号”将插入数组而不是符号“0”和“1”。函数iToBin()
将高位编码到buff
数组的第一个元素中,然后buff[0]
是转换后的数字的高位
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<stdint.h>
using namespace std;
char * iToBin(uint64_t n, char *buff, int len, const char *sym=(const char []){'0','1'});
char * iToBin(uint64_t n,char *buff,int len, const char *sym)
{
uint64_t k=1;
*(buff+ --len)=0;
do {
*(buff+ --len)=(n&k)?sym[1]:sym[0];
k<<=1;
} while(k && len);
return buff;
}
int main(void) {
uint64_t value;
int len=0;
char * buff;
buff=new char[sizeof(value)*8+1];
if (buff==NULL) {
cout << "Not enough memory" << endl;
return 1;
}
do {
cout << "Insert the value to convert: ";
cin >> value;
//len=(log2(value)+1); //number of digit
//len++; // to insert the string0 terminator
//It's better to use this to compute the number of bits!
len=64;
while(!(value & (1ULL<<(len-1))) && len>1) len--;
len++; //to insert string 0 terminator
iToBin(value,buff,len);
int numOnes=0;
for(int i=0;i<len-1;i++) {
if (buff[i]=='1') {
numOnes++;
}
}
cout << buff << " contains " << numOnes << " 1" << endl;
} while(value!=0);
delete buff;
return 0;
}
您可以使用以下代码生成一个代码,其中位由0和1数值表示:
sym[0]=0;sym[1]=1;
但是缓冲区结果作为以C 0结尾的字符串不会有用!我很困惑。通过传递int*,我传递的是在main
中创建的指针,并且只在toBinNum()中修改它的值
。由于指针存在于main中,为什么在作用域返回到main
后,它和任何分配给它的新的值都不会保留?此外,为什么通过int*&
将其作为int*的引用会允许以后分配的新的内存保留下来?@Alex G,正如我所说的,参数是一个本地v具有块作用域的函数的变量。它获取相应参数值的副本。请参阅我的