好奇,如果有人知道(或可以轻松测试)引用然后取消引用数组所需的时间.
my @foo = (0..1500000); # (~1.5M nodes).
join('',@{\@foo}); # any noticeable time difference vs join('',@foo) ?
Run Code Online (Sandbox Code Playgroud)
这显然没有正当理由,但我遇到了不合理的代码:)
可能重复:
可以在其范围之外访问局部变量的内存吗?
请考虑以下简单的C++代码:
#include <iostream>
struct Test
{
Test( int i )
: ref( i ),
ptr( &i ) {}
int &ref;
int *ptr;
};
int main()
{
Test t( 5 );
std::cout << t.ref << std::endl;
std::cout << *t.ptr << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Test类存储指针和对生活在堆栈上的局部变量的引用.我会假设从Test构造函数返回后我被破坏了.但显然事实并非如此.因为这是程序的输出:
5
134513968
Run Code Online (Sandbox Code Playgroud)
访问指针的结果是我所期望的:随机值随每次运行而变化.但是引用访问总是导致5 - 只是局部变量i仍然存在.
任何人都可以向我解释这种行为吗?我在64位Linux(版本4.6.3)上使用g ++.
此致,enuhtac
我似乎无法管理访问向量元素的语法,其指针包含在结构中.更多MWE之后:
#include <vector>
#include <stdio.h>
typedef struct vectag
{
std::vector<float> *X;
} vec;
int main ()
{
vec A;
A.X = new std::vector<float>(0);
A.X->push_back(5.0);
// This next line is the problem:
float C = A.X[0];
printf("%f\n", C);
return 1;
}
Run Code Online (Sandbox Code Playgroud)
GCC(G ++)说
14:24: error: cannot convert ‘std::vector<float>’ to ‘float’ in initialization
Run Code Online (Sandbox Code Playgroud)
当然,这是非常正确的.在该行中float C = A.X[0];,BX [0]将是正确的,如果X不是指针(召回std::vector<float> *X;).在operator []之前解除引用X的正确语法是什么,以便我可以访问X的元素?
PS我知道成员函数at(),它不是我的选项,因为我不想要范围检查的开销.这是性能关键代码的一部分.
int main(int argc, const char * argv[])
{
int age = 40;
float gpa = 3.25f;
char grade ='A';
double fun = 2.000043f;
char companyName[20] = "O'Brien Enterprises";
int *pAge = &age;
int *pGpa = &gpa;
int *pGrade = &grade;
int *pFun = &fun;
int *pCompanyName = &companyName;
printf("Value of variables through pointers:\n");
printf("age = %i\n", *pAge);
printf("gpa = %f\n",*pGpa);
printf("grade = %c\n", *pGrade);
printf("fun = %d\n", *pFun);
printf("companyName = %s\n", *pCompanyName);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我运行此代码时,Xcode会回复大量的警告和错误.当声明和初始化除了age它之外的所有变量的指针时incompatible pointer …
预备要点:我需要做什么改变才能在我的记录中显示正确的头/尾值?
编辑1:一旦有超过1个线程,Record内部的整数数组似乎会填充随机值.
我一直试图调试这几天了.我的代码已完成并完全执行.(众所周知,我是一名学生而不是假装成为一名专业程序员.)
在我的多线程硬币投掷程序中,我试图捕获每个线程中出现头或尾的次数.我正在翻硬币总共100,000,000次.(一亿.)
记录类中数组中的元素没有正确累积.我知道我不需要使用互斥锁,因为每个线程都访问一个独特的线程内存位置.但是线程正在更新错误的值,这不应该发生.
以下是我的调试示例.
下面是完全可执行的代码示例,然后是示例输出.此外,这里还链接到Github上的完整代码:
#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
#include <random>
#include <algorithm>
#include <time.h>
#include <strstream>
#include <random>
using namespace std;
default_random_engine dre;
uniform_int_distribution<int> Tosser(0,1);
struct Record {
Record();
~Record();
int numThreads;
int *heads;
int *tails;
time_t startTime;
time_t stopTime;
time_t duration;
int timesToToss;
};
Record::Record(): numThreads(0), heads(NULL), tails(NULL), startTime(NULL), stopTime(NULL), timesToToss(0){}
Record::~Record() {
startTime = NULL;
stopTime = NULL;
duration = NULL;
timesToToss = NULL;
delete [] heads; …Run Code Online (Sandbox Code Playgroud) 如果我有一个 std::vector,我可以访问一个成员,因为方括号运算符在 vector 类中被重载。如果我有一个指向向量的指针,我可以取消引用该指针并使用此运算符。但是使用箭头 -> 运算符它不会让我使用它。例子:
// Excuse the UB here, it's just for illustration
std::vector<int> myVector;
std::vector<int>* pToVector;
myVector[4] = 0; // Works fine
(*pToVector)[4] = 0; // Works fine
pToVector->[4] = 0; // Doesn't work
(pToVector->)[4] = 0; // Doesn't work
Run Code Online (Sandbox Code Playgroud)
好像 -> 箭头运算符取消了指针的引用,是否有理由不期望这会起作用?或者它只是关于语言的那些事情之一?
谢谢。
我已经认识到,当移动取消引用Box的时*Box::new(_),它不会调用Deref::deref或DerefMut::deref_mut;它确实移动了值,这意味着*Box::new(_)拥有所有权,而不是对引用的取消引用。
一个例子:
let a = Box::new(String::from("hello");
let b = *a;
Run Code Online (Sandbox Code Playgroud)
我了解到这Box是一个非凡的结构,因此在数据移动的情况下,它实际上像引用一样取消引用(没有Deref特征)。
Box移动过程中,堆中分配的内存发生了什么变化?它被释放了吗?是用一堆零代替的吗?是否仍然没有任何访问方式?
我知道分配的内存在删除String::from时将被释放b。我对数据并不好奇str type hello,我对大小为 的内存感到好奇size of String。
我如何显式取消引用Box没有Deref特征的?当我尝试时,它会Box通过调用自动借用Deref::deref。
let a = Box::new(String::from("hello"));
fn test(i: &String) {}
test(&(*a));
Run Code Online (Sandbox Code Playgroud)
编译器推断不需要 move *a,因此看起来它是通过特征取消引用,而不是直接取消引用。
本例成功消耗了盒子和字符串:
let a = Box::new(String::from("hello"));
fn test(i: &String) {}
test(&(*a));
Run Code Online (Sandbox Code Playgroud)
我有一个代码flush[*it % 4].push_back(*(it++) /= 4);,它意味着在递增it迭代器之前push_back新值(旧值/ 4),它是否正确或如何以最快的方式从迭代器获取值,除以4,存储它,在push_back中使用新值然后增加迭代器?
下面的代码给了我一个分段错误,我尝试了很多不同的东西,但无法理解为什么它不起作用.我对C++很陌生,所以如果这个问题可能有点容易,我很抱歉;)这是我的代码:
class Line2D
{
public:
Point2D punkt;
double dx, dy;
void set_values(Point2D p, double d1, double d2);
Point2D* getIntersectionPoint(Line2D& line2);
};
void Line2D::set_values(Point2D p, double d1, double d2)
{
punkt = p;
dx = d1;
dy = d2;
}
Point2D* Line2D::getIntersectionPoint(Line2D& line2)
{
double a, b;
Point2D* intersec;
double det = dx*line2.dy - dy*line2.dx;
if(det == 0)
{
return NULL;
}
else
{
double c1 = line2.punkt.k1 - punkt.k1;
double c2 = line2.punkt.k2 - punkt.k2;
a = (line2.dy*c1 - line2.dx*c2)/det; …Run Code Online (Sandbox Code Playgroud) 我今天遇到了一个问题,并且能够快速找到并修复它,但是并不完全理解为什么golang语义就是这样.
我正在使用Go 1.10.
package main
import "fmt"
type T struct {
V int
}
var testT = T{}
func main() {
t := &(*(&testT))
t.V = 4
fmt.Println(t, testT) // test.V == t.V -> t == &testT
t1 := &testT
t2 := *t1
t3 := &t2
t3.V = 5
fmt.Println(t3, testT) // t3.V == 4 and test.T == 4 -> t3 != &testT
}
Run Code Online (Sandbox Code Playgroud)
&{4} {4}
&{5} {4}
Run Code Online (Sandbox Code Playgroud)
我期望不要等于&testT所以有与t3相同的语义,但是如果我将中间结果存储在变量中,我会看到&(*(&))序列没有相同的语义
这种行为的原因是什么?